SQL Server 2008:删除重复的行

SQL Server 2008:删除重复的行,sql,sql-server-2008,duplicates,Sql,Sql Server 2008,Duplicates,我的表中有重复的行,如何根据单个列的值删除它们 乙二醇 您可以从cte中删除: WITH cte AS (SELECT *,ROW_NUMBER() OVER(PARTITION BY uniqueid ORDER BY col2)'RowRank' FROM Table) DELETE FROM cte WHERE RowRank > 1 ROW_NUMBER函数为每一行指定一个数字。PARTITION BY用于为该组中的每个项目重新编号,在这种情况下,un

我的表中有重复的行,如何根据单个列的值删除它们

乙二醇

您可以从cte中删除:

WITH cte AS (SELECT *,ROW_NUMBER() OVER(PARTITION BY uniqueid ORDER BY col2)'RowRank'
             FROM Table)
DELETE FROM cte 
WHERE RowRank > 1
ROW_NUMBER函数为每一行指定一个数字。PARTITION BY用于为该组中的每个项目重新编号,在这种情况下,uniqueid的每个值将从1开始编号,并从1开始递增。ORDER BY确定数字的顺序。由于每个uniqueid从1开始编号,因此任何行数大于1的记录都有一个重复的uniqueid

要了解ROW_NUMBER函数的工作原理,只需尝试一下:

SELECT *,ROW_NUMBER() OVER(PARTITION BY uniqueid ORDER BY col2)'RowRank'
FROM Table
ORDER BY uniqueid
您可以调整ROW_NUMBER函数的逻辑,以调整要保留或删除的记录

例如,您可能希望分多个步骤执行此操作,首先删除具有相同姓氏但不同姓氏的记录,您可以通过以下方式将姓氏添加到分区:

从uniqueid='1'和col2='john'所在的表中删除 或者你把col2='john'换成col2='johnny'。取决于要删除的记录


您最初是如何得到两个相同的唯一ID的?

这里有一个简单的魔法,可以删除重复的ID

DECLARE @du TABLE (
    id INT,  
    Name VARCHAR(4)
)

INSERT INTO @du VALUES(1,'john')
INSERT INTO @du VALUES(2,'jane')
INSERT INTO @du VALUES(1,'john')

;WITH dup (id,dp)
AS
(SELECT id
, ROW_NUMBER() OVER(PARTITION BY id ORDER BY Name) AS dp
FROM @du)
DELETE FROM dup
WHERE dp > 1

SELECT *
FROM @du
select * into NewTable from ExistingTable
union
select * from ExistingTable;

您可能有一个行id,它在插入时由DB分配,并且实际上是唯一的。在我的示例中,我将此称为rowId

rowId |uniqueid |col2  |col3
----- |-------- |----  |----
1      10        john   simpson
2      20        sally  roberts
3      10        johnny simpson
您可以通过对应该是唯一的内容(无论是一列还是多列)进行分组来删除重复项,然后从每个组中获取一个rowId,并删除除这些rowId之外的所有内容。在内部查询中,除了重复的行之外,表中的所有内容都将具有rowId

select * 
--DELETE 
FROM MyTable 
WHERE rowId NOT IN 
(SELECT MIN(rowId) 
 FROM MyTable 
 GROUP BY uniqueid);

您也可以使用MAX而不是MIN来获得类似的结果。

您有许多方法可以删除重复记录,其中一些方法如下

删除重复记录的不同方法

使用行数函数和CTE

  with CTE(DuplicateCount) as  ( SELECT  ROW_NUMBER() OVER
(PARTITION by UniqueId order by UniqueId ) as DuplicateCount from
Table1 ) Delete from CTE where DuplicateCount > 1

  .Without using CTE*

Delete DuplicateCount from ( Select Row_Number() over(Partition by
UniqueId order by UniqueId) as Dup from Table1 ) DuplicateCount 
where DuplicateCount.Dup > 1

 .Without using row_Number() and CTE

Delete from Subject where RowId not in(select Min(RowId ) from
Subject group by UniqueId)

你会保留哪一个?约翰尼还是约翰?我不介意我保留哪一个。这是最干净的方法。你能解释一下“SELECT*,ROW_NUMBER OVERPARTITION BY ID,ORDER BY col2'RowRank'FROM Table”是什么吗?当然,更新了答案,包括对ROW_NUMBERBy ID的描述。你的意思是UniqueId-按ID分区。还有为什么Orderby col2-我不在乎col2是否重复,我想删除UniqueId的副本,不管它是否落后。是的,在你的情况下,ID=UniqueId。ORDER BY也可以是ORDER BY SELECT 1,使其具有任意性。同样,PARTITION BY定义了将从1-n开始编号的字段,ROW_NUMBER函数中需要ORDER BY,因此实际上它决定了哪些重复项被删除,哪些不被删除。这只回答了OP给出的非常具体的示例,因为这只是一个例子,他们大概希望有一个更通用的解决方案,这是硬编码的例子没有?我仍在试图弄清楚我是如何被愚弄的。
select * 
--DELETE 
FROM MyTable 
WHERE rowId NOT IN 
(SELECT MIN(rowId) 
 FROM MyTable 
 GROUP BY uniqueid);
  with CTE(DuplicateCount) as  ( SELECT  ROW_NUMBER() OVER
(PARTITION by UniqueId order by UniqueId ) as DuplicateCount from
Table1 ) Delete from CTE where DuplicateCount > 1

  .Without using CTE*

Delete DuplicateCount from ( Select Row_Number() over(Partition by
UniqueId order by UniqueId) as Dup from Table1 ) DuplicateCount 
where DuplicateCount.Dup > 1

 .Without using row_Number() and CTE

Delete from Subject where RowId not in(select Min(RowId ) from
Subject group by UniqueId)