T-SQL:删除所有重复的行,但保留一个

可能重复:
SQL – 如何删除重复的行?

我有一个非常大量的行的表。 重复是不允许的,但由于如何创build行的问题,我知道这个表中有一些重复。 我需要从关键列的angular度消除额外的行。 其他一些列可能有稍微不同的数据,但我不关心这一点。 我仍然需要保留这些行之一。 SELECT DISTINCT将不起作用,因为它在所有列上操作,我需要根据键列来抑制重复项。

我怎样才能删除额外的行,但仍然有效地保持一个?

你没有说你正在使用的是什么版本,但是在SQL 2005及以上版本中,你可以使用OVER子句的公用表expression式。 它有点像这样:

WITH cte AS ( SELECT[foo], [bar], row_number() OVER(PARTITION BY foo, bar ORDER BY baz) AS [rn] FROM TABLE ) DELETE cte WHERE [rn] > 1 

玩弄它,看看你得到什么。

(编辑:为了有帮助,有人编辑了CTE中的ORDER BY子句,要清楚的是,你可以在这里命令你想要的任何东西,它不一定是cte返回的列之一,事实上,这里的一个常见用例是“foo,bar”是组标识符,“baz”是某种时间标记,为了保持最新状态,您可以使用ORDER BY baz desc

示例查询:

 DELETE FROM Table WHERE ID NOT IN ( SELECT MIN(ID) FROM Table GROUP BY Field1, Field2, Field3, ... ) 

这里的fields是你想要对重复行进行分组的列。

这是我的一个可以运行的例子。 请注意,这只适用于Id唯一的情况,并且在其他列中有重复的值。

 DECLARE @SampleData AS TABLE (Id int, Duplicate varchar(20)) INSERT INTO @SampleData SELECT 1, 'ABC' UNION ALL SELECT 2, 'ABC' UNION ALL SELECT 3, 'LMN' UNION ALL SELECT 4, 'XYZ' UNION ALL SELECT 5, 'XYZ' DELETE FROM @SampleData WHERE Id IN ( SELECT Id FROM ( SELECT Id ,ROW_NUMBER() OVER (PARTITION BY [Duplicate] ORDER BY Id) AS [ItemNumber] -- Change the partition columns to include the ones that make the row distinct FROM @SampleData ) a WHERE ItemNumber > 1 -- Keep only the first unique item ) SELECT * FROM @SampleData 

结果是:

 Id Duplicate ----------- --------- 1 ABC 3 LMN 4 XYZ 

不知道为什么这是我首先想到的…绝对不是最简单的方法去,但它的工作原理。