如何在以下情况下使用SQL删除重复项

时间:2019-02-27 17:55:06

标签: sql sql-server sql-server-2008 sql-server-2012

如何删除重复项。在这里我只保留不同的记录(记录)

ID          LAST_MODIFIED_DATE      rn
44849691    2019-01-29 00:00:09.000 1
44849691    2019-01-29 00:31:30.000 2
44849691    2019-01-29 00:31:30.000 2
44849691    2019-01-29 00:31:30.000 2
44849691    2019-01-29 00:31:30.000 2
44849691    2019-01-29 00:31:30.000 2
44849691    2019-01-29 00:31:30.000 2
44849691    2019-01-29 00:31:30.000 2
44849691    2019-01-29 00:31:30.000 2
44849691    2019-01-29 00:31:30.000 2
44849691    2019-01-29 00:31:30.000 2
44849691    2019-01-29 00:31:30.000 2

使用 RANK 分区功能

2 个答案:

答案 0 :(得分:2)

使用ROW_NUMBER()窗口函数代替RANK()。在CTE中查询,然后简单地DELETE从CTE中记录。这将回到您的实际表中。

; WITH cte1 AS (
    SELECT ROW_NUMBER() OVER ( PARTITION BY ID, LAST_MODIFIED_DATE ORDER BY ( SELECT NULL ) ) AS rn
    FROM t1 
) 
DELETE FROM cte1 WHERE rn > 1 ;

https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=0b1e4bba4577837cf7c9cedbd26e3e36

请记住,如果删除大量记录,则将大大增加日志,并且需要重建所有索引。

如果空间有限,那么Gordon仅选择一个新表的答案将是最好的。这实际上取决于表的其余部分。

我们要处理多少行?数据上有索引吗?

编辑说明::我将ROW_NUMBER()函数更改为ORDER BY ( SELECT NULL )而不是实际字段。在这种情况下,由于我们正在寻找重复项,因此我们似乎并不在乎顺序如何。

编辑2:

https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=1f3eb371dbe1cfa84291e5aaa566cc76

该链接演示了额外的一列,这将阻止我们真正重复的行。但是我们仍然能够删除基于IDLAST_MODIFIED_DATE的记录。但是,请注意,除非您在ORDER BY ....中指定其他字段,否则被视为“重复项”的行在某种程度上是任意的。

答案 1 :(得分:1)

您有很多重复项。仅仅创建一个新表怎么样?

select distinct t.*
into distinct_t
from t;

然后,您可以根据需要重新插入数据:

truncate table t;

insert into t
    select * from distinct_t;