查询以选择“更完整”的重复记录

时间:2016-08-15 15:57:15

标签: sql sql-server duplicates common-table-expression

我正在尝试编写一个SQL查询,它将选择“更完整”的副本。例如,如果我们的表包含以下4个字段:名称,电话,电子邮件,CompanyId,以及Name和&两个记录的CompanyId相等,但其中一个包含电话和/或电子邮件,另一个记录将这两个字段留空,那么记录集中只有完成的记录可用。

我以为我的查​​询失败了,但如果不存在“更完整”的记录,那么该记录要么完全省略,要么在记录集中保持重复(取决于我如何修改查询)。我不确定是否有更好的方法可以做到这一点,不会导致任何数据丢失/重复。现在,我能想到的是UNION更多其他查询,但我觉得必须有更好的方法。我正在使用CTE获取原始数据,然后我正在尝试操作它以删除重复项:

;WITH Contacts AS ( 
     -- LONG QUERY HERE THAT UNIONS NECESSARY Tables & XML Columns AND returns a recordset with Name, Email, Phone, and ClientId
)
SELECT u.* FROM Contacts u
INNER JOIN (
    SELECT Name, ClientId, Count(*) AS ct FROM Contacts 
    GROUP BY Name, ClientId
    HAVING COUNT(*) > 1
) AS g
ON u.Name = g.Name AND u.ClientId = g.ClientId
WHERE Phone IS NOT NULL AND Email IS NOT NULL
UNION
SELECT u.* FROM Contacts u
INNER JOIN (
    SELECT Name, ClientId, Count(*) AS ct FROM Contacts 
    GROUP BY Name, ClientId
    HAVING COUNT(*) = 1
) AS h
ON u.Name = h.Name AND u.ClientId = h.ClientId

如果需要再合并几个查询并不是什么大问题,但看起来可能有更好的方法来解决这个问题。有什么建议吗?

编辑:示例数据

Name     |  Phone         |   Email       |  ClientId
------------------------------------------------------
Person1  |  NULL          |  NULL         | 42
Person1  |  555-555-5555  | test@blah.org | 42
Person2  | NULL           | NULL          | 21
Person2  | NULL           | NULL          | 21
Person3  | 555-555-5555   | NULL          | 79
Person3  | NULL           | NULL          | 79
Person4  | 555-555-5555   | NULL          | 49
Person4  | NULL           | test@blah.org | 49
Person5  | 555-555-5555   | NULL          | 91
Person5  | 555-555-5555   | test@blah.org | 91
Person6  | 555-555-5555   | NULL          | 91

查询后返回的数据集 -

Name     |  Phone         |   Email       |  ClientId
------------------------------------------------------
Person1  |  555-555-5555  | test@blah.org | 42
Person2  | NULL           | NULL          | 21
Person3  | 555-555-5555   | NULL          | 79
Person4  | 555-555-5555   | test@blah.org | 49
Person5  | 555-555-5555   | test@blah.org | 91
Person6  | 555-555-5555   | NULL          | 91

Person4的数据合并是理想的情况,但不一定是我在这个SO问题中寻找的答案。在那种填充名称或电子邮件的情况下,只要没有任何数据丢失,我就可以使用重复项。

2 个答案:

答案 0 :(得分:2)

这将返回最好的"每name行。最佳意味着额外列的最大数量(MailPhone)不为空。

select  top(1) with ties *
from Contact
order by row_number() over (partition by Name order by 
       case when Phone is null then 0 else 1 end + case when Email is null then 0 else 1 end desc)

答案 1 :(得分:-1)

试试这个

 WITH CT AS(
           SELECT Name, Phone, Email, CompanyId,
    --This part determines duplicates by field 
               RN = ROW_NUMBER()OVER(PARTITION BY Name,CompanyId  ORDER BY Name)
           FROM Contacts
        )
        select FROM CT WHERE email <> '' and phone <> ''

要根据特定列选择重复项,请在此处

ROW_NUMBER()OVER(PARTITION BY {column1}, {column2}.....