删除表中的多个重复行

时间:2010-10-12 17:55:07

标签: sql sql-server tsql

我确信以前曾经问过,但我很难找到它。

我在一个表中有多组重复项(3个记录表示一个,2个表示另一个表等) - 多行存在多个表。

以下是我想要删除它们的内容,但是我必须运行脚本,但有许多重复项:

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

这在某种程度上很有效。我需要为每组重复项运行它,然后它只删除1(这就是我现在所需要的)。

感谢您的帮助/评论!

4 个答案:

答案 0 :(得分:7)

如果表上有一个键列,那么您可以使用它来唯一标识表中的“不同”行。

只需使用子查询来标识唯一行的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

答案 1 :(得分:2)

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

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

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')
John Sansom在previous answer

中的

-- 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'

答案 2 :(得分:1)

您也可以使用ROW_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

答案 3 :(得分:0)

SET ROWCOUNT 1    
DELETE Table    
FROM Table a    
WHERE (SELECT COUNT(*) FROM Table b WHERE b.Code = a.Code ) > 1    
WHILE @@rowcount > 0    
  DELETE Table    
  FROM Table a    
  WHERE (SELECT COUNT(*) FROM Table b WHERE b.Code = a.Code ) > 1    
SET ROWCOUNT 0

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