Sql 删除表中的多个重复行

Sql 删除表中的多个重复行,sql,sql-server,tsql,Sql,Sql Server,Tsql,我在一个表中有多组重复项(一个表有3条记录,另一个表有2条记录,等等)——多行中有1条以上的记录 下面是我删除它们的想法,但是我必须运行脚本,不管有多少副本: set rowcount 1 delete from Table where code in ( select code from Table group by code having (count(code) > 1) ) set rowcount 0 这在一定程度上很有效。我需要对每组重复项运行此操作,然后它只删

我在一个表中有多组重复项(一个表有3条记录,另一个表有2条记录,等等)——多行中有1条以上的记录

下面是我删除它们的想法,但是我必须运行脚本,不管有多少副本:

set rowcount 1
delete from Table
where code in (
  select code from Table 
  group by code
  having (count(code) > 1)
)
set rowcount 0

这在一定程度上很有效。我需要对每组重复项运行此操作,然后它只删除1行(这是我现在所需要的)。

如果表中有键列,则可以使用此操作唯一地标识表中的“不同”行

只需使用子查询来标识唯一行的ID列表,然后删除此集合之外的所有内容。类似于

create table #TempTable
(
    ID int identity(1,1) not null primary key,
    SomeData varchar(100) not null
)

insert into #TempTable(SomeData) values('someData1')
insert into #TempTable(SomeData) values('someData1')
insert into #TempTable(SomeData) values('someData2')
insert into #TempTable(SomeData) values('someData2')
insert into #TempTable(SomeData) values('someData2')
insert into #TempTable(SomeData) values('someData3')
insert into #TempTable(SomeData) values('someData4')

select * from #TempTable

--Records to be deleted
SELECT ID
FROM #TempTable
WHERE ID NOT IN
(
    select MAX(ID)
    from #TempTable
    group by SomeData
)

--Delete them
DELETE
FROM #TempTable
WHERE ID NOT IN
(
    select MAX(ID)
    from #TempTable
    group by SomeData
)

--Final Result Set
select * from #TempTable

drop table #TempTable;
或者,您可以使用CTE,例如:

WITH UniqueRecords AS
(
    select MAX(ID) AS ID
    from #TempTable
    group by SomeData
)
DELETE A
FROM #TempTable A
    LEFT outer join UniqueRecords B on
        A.ID = B.ID
WHERE B.ID IS NULL

这将删除所有重复的行,但如果要根据它们进行比较,可以添加属性。

将唯一行复制到临时表中通常更有效,
删除源表,重命名回临时表

我重用了#tentable的定义和数据,这里称为SrcTable,因为不可能将临时表重命名为常规表)

作者:约翰·桑森


您也可以使用
ROW\u NUMBER()
函数筛选重复项

;WITH [CTE_DUPLICATES] AS 
(
SELECT RN = ROW_NUMBER() OVER (PARTITION BY SomeData ORDER BY SomeData)
FROM #TempTable
) 
DELETE FROM [CTE_DUPLICATES] WHERE RN > 1

您希望保留哪一个副本--第一个/最低,还是最新的/最高?对于哪个版本的SQL Server?可以使用-max-ID。SQL Server 2000(是的,我知道)可能重复感谢链接,Martin-我担心这可能是重复。刚刚注意到OP无论如何都在SQL Server 2000上,但是使用CTE可以更有效地执行此操作,因为这个问题的OP在SQL Server 2000上。如果使用此策略,重命名后应该读取密钥,约束、标识值、索引和关系
create table SrcTable
(
    ID int identity(1,1) not null primary key,
    SomeData varchar(100) not null
)

insert into SrcTable(SomeData) values('someData1')
insert into SrcTable(SomeData) values('someData1')
insert into SrcTable(SomeData) values('someData2')
insert into SrcTable(SomeData) values('someData2')
insert into SrcTable(SomeData) values('someData2')
insert into SrcTable(SomeData) values('someData3')
insert into SrcTable(SomeData) values('someData4')
-- cloning "unique" part
SELECT * INTO TempTable 
FROM SrcTable --original table
WHERE id IN  
(SELECT MAX(id) AS ID
FROM SrcTable
GROUP BY SomeData);
GO;

DROP TABLE SrcTable
GO;

sys.sp_rename 'TempTable', 'SrcTable'
;WITH [CTE_DUPLICATES] AS 
(
SELECT RN = ROW_NUMBER() OVER (PARTITION BY SomeData ORDER BY SomeData)
FROM #TempTable
) 
DELETE FROM [CTE_DUPLICATES] WHERE RN > 1