我如何删除重复的行?
从相当大的SQL Server
表中删除重复行的最佳方法是什么(即300,000多行)?
由于RowID
标识字段的存在,行当然不会是完美的重复项。
MyTable的
RowID int not null identity(1,1) primary key,
Col1 varchar(20) not null,
Col2 varchar(2048) not null,
Col3 tinyint not null
假设没有空值, GROUP BY
唯一列,并SELECT
MIN (or MAX)
RowId作为要保留的行。 然后,删除没有行ID的所有东西:
DELETE FROM MyTable
LEFT OUTER JOIN (
SELECT MIN(RowId) as RowId, Col1, Col2, Col3
FROM MyTable
GROUP BY Col1, Col2, Col3
) as KeepRows ON
MyTable.RowId = KeepRows.RowId
WHERE
KeepRows.RowId IS NULL
如果你有一个GUID而不是一个整数,你可以替换
MIN(RowId)
同
CONVERT(uniqueidentifier, MIN(CONVERT(char(36), MyGuidColumn)))
另一种可能的方式是
;
--Ensure that any immediately preceding statement is terminated with a semicolon above
WITH cte
AS (SELECT ROW_NUMBER() OVER (PARTITION BY Col1, Col2, Col3
ORDER BY ( SELECT 0)) RN
FROM #MyTable)
DELETE FROM cte
WHERE RN > 1;
我正在使用上面的ORDER BY (SELECT 0)
,因为它是任意的,在发生平局时要保留哪一行。
例如,要使用RowID
顺序保留最新的一个,可以使用ORDER BY RowID DESC
执行计划
执行计划通常比接受的答案更简单,更高效,因为它不需要自加入。
但情况并非总是如此。 GROUP BY
解决方案可能更GROUP BY
一个地方是散列聚合将优先于流聚合而被选择的情况。
ROW_NUMBER
解决方案将始终提供几乎相同的计划,而GROUP BY
策略则更加灵活。
可能有利于哈希聚合方法的因素是
在第二种情况下极端版本(如果有在每个很多重复极少数群体)一个也考虑简单地插入的行保持到一个新表,然后TRUNCATE
-ing原件和复制回相比,删除,以减少日志记录这些行的比例非常高。
有一篇关于删除Microsoft支持网站上的重复内容的好文章。 这是非常保守的 - 他们让你在单独的步骤中做所有事情 - 但它应该可以很好地对付大型表格。
过去我使用自连接来完成这个任务,但它可能会被HAVING子句弄糟:
DELETE dupes
FROM MyTable dupes, MyTable fullTable
WHERE dupes.dupField = fullTable.dupField
AND dupes.secondDupField = fullTable.secondDupField
AND dupes.uniqueField > fullTable.uniqueField
链接地址: http://www.djcxy.com/p/4215.html
上一篇: How can I remove duplicate rows?
下一篇: Android error: Failed to install *.apk on device *: timeout