2014-10-01 71 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