2014-10-01 66 views
1

我有一個場景,我正在編寫SQL Server Reporting Services以創建Tablular報表並卡住了一個點,在該點我得到一列的重複值。下面是從代碼輸出樣本:在SQL Server中處理Null值和重複記錄

AppID EmpID EmpName 
2002912 81555 NULL 
2002912 81588 Jenn - 81588 
2026880 9328 NULL 
2026880 9628 Brad - 09628 
2027065 92174 Julie - 92174 
2027065 92714 NULL 
2028989 72138 NULL 
2028989 91366 Alan - 91366 
2029233 17438 NULL 
2029233 53712 Brad - 53712 
2031585 37902 NULL 
2031588 17723 Richard - 17723 
2031591 54551 Paula - 54551 
2031593 52240 Sarah - 52240 
2031597 72778 Daisy - 72778 
2031603 12659 NULL 

通知第一coulmn(AppID)具有幾個重複和對應的列EmpName要麼Null或有一定的價值。我想消除所有重複的AppID's,其中EmpNamenull

如果對於唯一的AppID(請參考最後一行)沒有空值,我可以直截了當地處理大量數據,因此我也無法硬編碼。

另請注意,所有這三根柱子是從不同的表來,並已LEFT JOINAppID表。請讓我知道,如果你需要看代碼,我沒有粘貼在這裏,因爲它很複雜,但可能並不需要。

任何形式的幫助和建議是appreciated.Thank你

+0

使用'ROW_NUMBER OVER(分區通過的appid ORDER BY EmpName NULLS FIRST)'然後選擇行2.I'm不知道有關語法,但是這是一般的想法。或者如果NULLS FIRST不可用,則使用'ORDER BY(當EmpNAme爲NULL,否則爲0 ELSE 1 END時)。 – Mihai 2014-10-01 16:16:56

+0

我不想消除'AppID'唯一的'null'值。那麼在這種情況下,如何在重複的'AppID''和唯一'AppID''之間區分? – 2014-10-01 16:26:22

回答

4

使用ROW_NUMBER函數在CTE,然後挑中的第一行。雖然如果有多個不是NULL的EmpName,只會按字母順序得到第一個。

WITH AppAndEmp AS 
(
    SELECT 
     AppID 
     , EmpID 
     , EmpName 
     , ROW_NUMBER() OVER(PARTITION BY AppId 
         ORDER BY (CASE WHEN EmpName IS NULL THEN 0 ELSE 1 END) DESC 
           , EmpName) AS EmpOrder 

    FROM 
     dbo.App 
     LEFT JOIN dbo.Emp 
      ON App.AppId = Emp.AppId 
) 

SELECT 
    * 

FROM 
    AppAndEmp 

WHERE 
    EmpOrder = 1 
+0

+1不錯,將它添加到我的sqlfiddle示例中:http://sqlfiddle.com/#!3/67cf0/3/0 – Jakob 2014-10-01 16:42:02

+0

你的答案非常好,它確實有效。我知道我們不會僅僅評論說謝謝,但我真的無法阻止自己,因爲它爲我節省了很多時間來獲得答案。 – 2014-10-01 17:11:30

1

編輯

@djphatic:感謝您的評論。我糾正了我的答案。

-- These are those who have set a EmpName but have an invalid row too 
select * from data where AppID in (
    select AppID from data group by AppID having count(AppID) > 1 
) 
and empname is not null 
union 
-- These are those who MIGHT have set a EmpName or NULL 
select * from data where AppID in (
    select AppID from data group by AppID having count(AppID) = 1 
) 

=>SQLFiddle


對於緣故未能我離開我以前不正確回答到這裏:

你可以試試這個一個:

select AppID, min(empid) EmpID, min(EmpName) EmpName 
from data 
group by AppID 

SQLFiddle: http://sqlfiddle.com/#!3/67cf0/1/0

MIN忽略任何空值。

文檔的MIN在SQL Server:http://msdn.microsoft.com/en-us/library/ms179916.aspx

+0

這會給你不一致的結果。使用AppId 2026880的示例數據,您將獲得EmpId的9328和EmpName的Brad - 09628。 – mheptinstall 2014-10-01 16:42:16