【问题标题】:Issue deleting duplicate records in SQL在 SQL 中删除重复记录的问题
【发布时间】:2021-05-18 13:27:45
【问题描述】:

所以我似乎有一点时间,无法弄清楚为什么表中的某些副本没有被删除。我有一个名为 QUERY 的测试表,其中包含姓名、地址、出生日期、电话等。我希望删除 dups,但想保留电话所在的最新记录(最好但下面的代码不代表)不是空的。我下面的代码并不总是给出 0 结果。行的一个例子是:

+----------------------------------------------------------------+
|   first,last,DOB,address,city,state,phonenumber,validitydate   |
+----------------------------------------------------------------+
| steve,smith,19710922, 123 Here St, Miami, FL,9545551212,201902 |
| steve,smith,19710922, 123 Here St, Miami, FL,,202009           |
| steve,smith,19710922, 123 Here St, Miami, FL,9545551212,201802 |
+----------------------------------------------------------------+
WITH Records AS
(  
SELECT lastname, firstname, address, state, dateofbirth, phonenumber
    ,ROW_NUMBER() OVER (PARTITION BY lastname, firstname, address, state, dateofbirth, phonenumber order by validitydate) AS RecordInstance
    ,ROW_NUMBER() OVER (PARTITION BY lastname, firstname, address, state, dateofbirth, phonenumber order by
    CASE
        WHEN phonenumber ='' THEN 0
        WHEN phonenumber IS NOT NULL THEN 1
        Else 0
        END) as [ToInclude]
FROM query 
)
    
delete
FROM records
WHERE
    RecordInstance > 1
    and ToInclude = 0

有人看到我做错了什么吗?提前致谢

【问题讨论】:

  • ToInclude 永远不会是0,因为它的值是从ROW_NUMBER 派生的(从1 开始)。
  • 所以我只是将 ToInclude 从 = 0 替换为 >1,但确实留下了电话仍然空白的副本。在一个完美的世界里,第一条手机完好无损的记录应该只保留下来。
  • 您可以执行select * from Records where..... 来检查字段ToInclude 是否获得(所需的)正确值。
  • 因为具有必须最近有效期的行对于电话号码 @Sal 的值为 ''。如果这不正确,您不想查看最近的行,

标签: sql sql-server tsql duplicates


【解决方案1】:

我认为这就是你想要做的:

SELECT 
    RANK() OVER (PARTITION BY lastname, firstname, address, state, dateofbirth, phonenumber order by validitydate) AS RecordInstance
   ,COUNT(*) OVER (PARTITION BY lastname, firstname, address, state, dateofbirth, phonenumber) DUPS
FROM QUERY
WHERE DUPS > 2 
AND RecordInstance = 1
AND phonenumber <> '' -- maybe? if you really don't want to delete duplicates with no phone number

【讨论】:

  • 嗯计数需要一个参数
  • 是的,错过了*
【解决方案2】:

如果您需要的结果是删除所有电话号码不为空或为空的重复记录,那么您可以尝试以下查询:

WITH Records AS
(  
SELECT lastname, firstname, address, state, dateofbirth, phonenumber
    ,ROW_NUMBER() OVER (PARTITION BY lastname, firstname, address, state, dateofbirth, phonenumber order by validitydate) AS RecordInstance
    
FROM query where phonenumber<>'' and phonenumber is not null
)
    
delete
FROM records
WHERE
    RecordInstance > 1

【讨论】:

  • 这很接近,但仍然保留没有电话的记录,并且对具有相同电话的记录进行常规重复数据删除
  • 要删除所有没有电话号码的行吗?
  • 或者您想删除所有具有相同姓、名、地址、州、出生日期、电话号码和空白电话号码的行。
【解决方案3】:

试试

RecordInstance = ROW_NUMBER()   OVER(PARTITION BY LastName, FirstName,  Address, City, DateOfBirth ORDER BY PhoneNumber DESC, ValidityDate)

【讨论】:

    猜你喜欢
    • 2020-07-16
    • 2021-02-13
    • 2016-01-07
    • 2010-10-24
    • 1970-01-01
    • 1970-01-01
    • 2011-03-20
    • 1970-01-01
    相关资源
    最近更新 更多