如何使用 SQL 在以下场景中删除重复项
How to delete duplicate in the below scenario using SQL
如何删除duplicate.Here我只想保留不同的记录(records)
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 Partition 函数
您有很多重复项。只创建一个新的 table 怎么样?
select distinct t.*
into distinct_t
from t;
如果需要,您可以重新插入数据:
truncate table t;
insert into t
select * from distinct_t;
使用 ROW_NUMBER()
window 函数代替 RANK()
。在 CTE 中查询,然后只需 DELETE
来自 CTE 的记录。这将回到您的实际 table。
; 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
请记住,如果您删除大量记录,您的日志会显着增长,您将需要重建您拥有的所有索引。
如果您在 space 上受限,Gordon 的回答就是选择一个新的 table 将是最好的。这实际上取决于 table 的其余部分是什么样子。
我们正在处理多少行?数据上有索引吗?
编辑注意: 我将 ROW_NUMBER()
函数更改为 ORDER BY ( SELECT NULL )
而不是实际字段。在这种情况下,我们似乎并不关心顺序是什么,因为我们正在寻找重复项。
编辑 2:
https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=1f3eb371dbe1cfa84291e5aaa566cc76
link 表明有一个额外的列可以防止我们拥有真正重复的行。但是我们仍然可以删除基于ID
和LAST_MODIFIED_DATE
的记录。但是,请注意,被视为 "duplicates" 的行将有些随意,除非您在 ORDER BY ....
.
中指定另一个字段
如何删除duplicate.Here我只想保留不同的记录(records)
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 Partition 函数
您有很多重复项。只创建一个新的 table 怎么样?
select distinct t.*
into distinct_t
from t;
如果需要,您可以重新插入数据:
truncate table t;
insert into t
select * from distinct_t;
使用 ROW_NUMBER()
window 函数代替 RANK()
。在 CTE 中查询,然后只需 DELETE
来自 CTE 的记录。这将回到您的实际 table。
; 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
请记住,如果您删除大量记录,您的日志会显着增长,您将需要重建您拥有的所有索引。
如果您在 space 上受限,Gordon 的回答就是选择一个新的 table 将是最好的。这实际上取决于 table 的其余部分是什么样子。
我们正在处理多少行?数据上有索引吗?
编辑注意: 我将 ROW_NUMBER()
函数更改为 ORDER BY ( SELECT NULL )
而不是实际字段。在这种情况下,我们似乎并不关心顺序是什么,因为我们正在寻找重复项。
编辑 2:
https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=1f3eb371dbe1cfa84291e5aaa566cc76
link 表明有一个额外的列可以防止我们拥有真正重复的行。但是我们仍然可以删除基于ID
和LAST_MODIFIED_DATE
的记录。但是,请注意,被视为 "duplicates" 的行将有些随意,除非您在 ORDER BY ....
.