【问题标题】:delete specific duplicate records sql server 2008删除特定的重复记录sql server 2008
【发布时间】:2026-01-05 22:40:01
【问题描述】:

我的表中有以下 3 种情况的重复记录:

record      Adddate
22344222    2016-04-22 00:00:00.000
22344222    2016-05-06 00:00:00.000
22344222    2016-06-06 00:00:00.000
22344222    2016-06-20 00:00:00.000
22344222    2016-07-25 00:00:00.000
22344222    2016-09-26 00:00:00.000
22344222    2016-10-03 00:00:00.000
22344222    2016-10-26 00:00:00.000
22344222    2016-10-27 00:00:00.000
22344222    2016-10-28 00:00:00.000

22344223    2016-04-22 00:00:00.000
22344223    2016-04-22 00:00:00.000
22344223    2016-04-22 00:00:00.000
22344223    2016-04-22 00:00:00.000
22344223    2016-04-22 00:00:00.000
22344223    2016-04-22 00:00:00.000
22344223    2016-04-22 00:00:00.000
22344223    2016-04-22 00:00:00.000
22344223    2016-04-22 00:00:00.000
22344223    2016-04-22 00:00:00.000

22344224    2016-04-22 00:00:00.000
22344224    2016-04-23 00:00:00.000
22344224    2016-04-24 00:00:00.000
22344224    2016-04-25 00:00:00.000
22344224    2016-04-26 00:00:00.000
22344224    2016-06-10 00:00:00.000

我想删除所有重复记录,除了 2 行,第一行应该是添加日期最少的行,第二行 adddate 之间的日期差为 45 天。

在上述三种情况下,我应该只能保留以下数据

record      Adddate
22344222    2016-04-22 00:00:00.000
22344222    2016-05-06 00:00:00.000

22344223    2016-04-22 00:00:00.000

22344224    2016-04-22 00:00:00.000
22344224    2016-06-06 00:00:00.000

【问题讨论】:

  • 你会更好地格式化这个,IE使用代码标签并将其放入表格布局中
  • 您的意思是“确切”45 天,还是“至少”45 天?
  • 正好 45 天
  • datediff 之间是什么?
  • 45天后没有记录怎么办?

标签: sql-server


【解决方案1】:

试试这个:

With mad(record, minDat) as 
   (Select record, min(addDate)
    From myTable
    group by record)
Delete t
from mytable t join mad m 
   on m.record = t.Record
where t.adddate not in 
   (m.minDat, dateadd(day, 45, m.minDat))

问题是您在源数据中有 13 条记录 22344223 都是相同的。

如果你只想要这 13 个重复的副本,那么,删除记录后,

create table dbo.temp (record integer, addDate date)
Insert dbo.temp(record, addDate)
Select distinct record, addDate
from mytable
-- ------------------------
Drop table myTable
-- ------------------------
exec sp_Rename 'dbo.temp', 'dbo.mytable'   

【讨论】:

  • 在这种情况下,只需要保留第一行
  • 电脑怎么只删除第一行?它怎么知道哪个是第一个?行没有排序。如果有一列主键或输入的日期,那么很容易。当行相同时,无法使用单个标准 SQL 语句直接执行此操作。唯一的方法是创建一个新表,其中只有与该表不同的值,删除该表并重命名新表。
【解决方案2】:

由于没有提供表名,所以我使用了 Test 表名。

WITH cte AS
(SELECT   *, NumSeq = ROW_NUMBER() OVER (PARTITION BY record ORDER BY Adddate) FROM   dbo.Test)
DELETE  FROM cte
WHERE cte.NumSeq > 1
    AND NOT EXISTS ( SELECT 1
                       FROM cte AS A
                       INNER JOIN cte AS B
                                       ON B.NumSeq > 1
                                          AND   DATEDIFF( DAY, A.Adddate, B.Adddate ) = 45
                                          AND   A.record = B.record
                       WHERE A.NumSeq = 1
                             AND cte.record = B.record
                             AND cte.Adddate = B.Adddate
                   );

SELECT  * FROM  dbo.Test;

这将返回 4 行:

22344222 2016-04-22 00:00:00.000

22344222 2016-06-06 00:00:00.000

22344223 2016-04-22 00:00:00.000

22344224 2016-04-22 00:00:00.000

编辑: 请注意,所需的结果显示 5/6 作为 22344222 的第二行,但这不是 4/22 之后的 45 天。我的结果返回 6/6 的行。另外,如果我将 22344224 的 6/6 日期添加到源数据中,我的结果将改为返回 5 行。

【讨论】: