【问题标题】:Select subset of duplicate records in SQL Server在 SQL Server 中选择重复记录的子集
【发布时间】:2019-06-13 04:16:49
【问题描述】:

我需要在 SQL Server 2016 中选择重复记录的子集。下面是数据集和使用的代码。我只需要选择以红色突出显示的重复项。基本上,我只需要那些具有匹配 LName、FName、dateOfBirth、StreetAddress 值的重复记录,并且在 Source 中是 Nave NUll。同时,我只需要在上述字段中也匹配并且源值为“Company XYZ”的记录

IF OBJECT_ID('tempdb..#Dataset') IS NOT NULL DROP TABLE #Dataset
GO

create table #Dataset 
(
    ID int not null,
    LName varchar(50) null,
    Fname varchar(50) null,
    DateOfBirth varchar(50) null,
    StreetAddress varchar(50) null,
    Source varchar(50) null,
)

insert into #Dataset (ID, LName, Fname, DateOfBirth, StreetAddress, Source)
values
('1', 'John', 'Ganske', '37171', '  1223 Sunrise St', 'Company XYZ'),
('2', 'John', 'Ganske', '37171', '  1233 Sunrise St', 'Company XYZ'),
('4', 'Brent', 'Paine', '20723', '  5443 Fox Dr', Null),
('3', 'Brent', 'Paine', '20723', '  5443 Fox Dr', 'Company XYZ'),
('5', 'Adam', 'Smith', '22805', '  1254 Lake Ridge Ct', Null),
('6', 'Adam', 'Smith', '22805', '  1254 Lake Ridge Ct', Null),
('7', 'Adam', 'Smith', '22805', '  1254 Lake Ridge Ct', 'Company XYZ'),
('8', 'Timothy', 'Johnson', '36165', '  1278 Lee H-W', Null),
('9', 'Timothy', 'Johnson', '36165', '  1278 Lee H-W', Null),
('10', 'Judy', 'Wilson', '32579', '  5678 Dotties Dr', 'Company XYZ'),
('12', 'Peter', 'Pan', '37507', NULL, Null),
('11', 'Peter', 'Pan', '37507', NULL, 'Company XYZ');

--select * from #Dataset

select d.ID, d.LName, d.Fname, d.DateOfBirth, d.StreetAddress, d.Source 
from  #Dataset d
inner join (select 
                LName, Fname, DateOfBirth, StreetAddress 
            from #Dataset
            --where Source is not null
            group by 
                LName, Fname, DateOfBirth, StreetAddress 
            having count(*) > 1 ) b 
            on  d.LName = b.LName 
                and 
                d.Fname = b.Fname 
                and 
                d.DateOfBirth = b.DateOfBirth
                and
                d.StreetAddress = b.StreetAddress   

left outer join (select min(ID) as ID from #Dataset
            group by  LName, Fname, DateOfBirth, StreetAddress 
            having count(*) > 1 ) c 
            on d.ID = c.ID

我的输出如下所示:

【问题讨论】:

  • 不完全理解你为什么要加入这个表。如果您想显示重复项,则分组依据和计数告诉您具有这些值的重复行数。只需按列分组并添加计数(*)。

标签: sql-server group-by duplicates ssms-2016


【解决方案1】:

你可以使用ROW_NUMBER:

WITH cte AS (
 SELECT *,ROW_NUMBER() OVER(PARTITION BY LName,Fname,DateOfBirth,StreetAddress 
                            ORDER BY ID DESC) rn
 FROM #Dataset
)
SELECT *
FROM cte 
WHERE rn > 1
ORDER BY ID;

db<>fiddle demo

编辑:

WITH cte AS (
SELECT *, 
  ROW_NUMBER() OVER(PARTITION BY LName, Fname, DateOfBirth, StreetAddress 
                    ORDER BY ID DESC) rn,
  SUM(CASE WHEN Source = 'Company XYZ' THEN 1 ELSE 0 END) 
               OVER(PARTITION BY LName, Fname, DateOfBirth, StreetAddress) AS cnt
FROM #Dataset
)
SELECT *
FROM cte 
WHERE rn > 1
  AND cnt > 0
  AND [Source] IS NULL
ORDER BY ID;

db<>fiddle demo2

编辑 2

WITH cte AS (
SELECT *, 
  SUM(CASE WHEN Source IS NULL THEN 1 ELSE 0 END) OVER(PARTITION BY LName, Fname, DateOfBirth, StreetAddress) c1,
  SUM(CASE WHEN Source = 'Company XYZ' THEN 1 ELSE 0 END) OVER(PARTITION BY LName, Fname, DateOfBirth, StreetAddress) AS c2,
  COUNT(*) OVER(PARTITION BY LName, Fname, DateOfBirth, StreetAddress) c3
FROM #Dataset
)
SELECT *
FROM cte 
WHERE c1 > 0
  AND c2 > 0
  AND c3 > 1
  AND Source IS NULL
ORDER BY ID;

db<>fiddle demo3

【讨论】:

  • 感谢 Lukasz Szozda。我已经试过了。这不是一个选择。即使有了这个数据集,我也得到了 ID 为 8 的记录。但我不需要它
  • @enigma6205 你可以添加额外的条件
  • 我只是重新排列了我的代码和屏幕截图以使其更真实。请运行您的代码,您将看到需要注意的地方。
  • 代码的第二个版本几乎可以满足我的需要。但它仅适用于 3 个重复和更多。它适用于亚当史密斯行。但它没有选择在我的屏幕截图中以红色突出显示的其他人。我只需要调整 "rn >=" 非常感谢!
  • @enigma6205 最终方法:demo
猜你喜欢
  • 1970-01-01
  • 2011-08-11
  • 2012-04-23
  • 1970-01-01
  • 1970-01-01
  • 2015-05-06
  • 1970-01-01
  • 2018-08-31
  • 1970-01-01
相关资源
最近更新 更多