如何在SQL Server 2008中删除重复的行?
答案 0 :(得分:11)
最简单的方法是使用CTE(公用表表达式)。当我要导入原始数据时,我使用这种方法;我做的第一件事就是确保它没有重复 - 我每行都有一些独特的句柄。
<强>要点:强>
WITH numbered AS (
SELECT ROW_NUMBER() OVER(PARTITION BY [dupe-column-list] ORDER BY [dupe-column-list]) AS _dupe_num FROM [table-name] WHERE 1=1
)
DELETE FROM numbered WHERE _dupe_num > 1;
“dupe-column-list”部分列出了您希望值唯一的所有列。 ORDER BY是您在一组重复项中决定哪些行“获胜”并被删除的地方。 (“WHERE 1 = 1”只是个人习惯。)
它起作用的原因是因为Sql Server保留了对CTE中选择的每个源行的内部唯一引用。因此,当执行DELETE时,无论您在CTE的选择列表中放置什么,它都会知道要删除的确切行。 (如果你很紧张,你可以将“删除”更改为“SELECT *”,但由于你有重复的行,它不会有帮助;如果你可以唯一地识别每一行,你就不会读这个。)
示例:强>
CREATE TABLE ##_dupes (col1 int, col2 int, col3 varchar(50));
INSERT INTO ##_dupes
VALUES (1, 1, 'one,one')
, (2, 2, 'two,two')
, (3, 3, 'three,three')
, (1, 1, 'one,one')
, (1, 2, 'one,two')
, (3, 3, 'three,three')
, (1, 1, 'one,one')
, (1, 2, '1,2');
在8行中,你有5个涉及重复问题;需要删除3行。你可以看到这个问题:
SELECT col1
, col2
, col3
, COUNT(1) AS _total
FROM ##_dupes
WHERE 1=1
GROUP BY col1, col2, col3
HAVING COUNT(1) > 1
ORDER BY _total DESC;
现在运行以下查询以删除重复项,从每组重复项中留下1行。
WITH numbered AS (
SELECT ROW_NUMBER() OVER(PARTITION BY col1, col2, col3 ORDER BY col1, col2, col3) AS _dupe_num FROM ##_dupes WHERE 1=1
)
DELETE FROM numbered WHERE _dupe_num > 1;
现在你剩下5行,其中没有一行是重复的。
答案 1 :(得分:4)
添加主键。说真的,每张桌子应该有一张。它可以是一个标识,您可以忽略它,但要确保每个表都定义了一个主键。
想象一下,你有一个像这样的表:
create table T (
id int identity,
colA varchar(30) not null,
colB varchar(30) not null
)
然后你可以这样说:
delete T
from T t1
where exists
(select null from T t2
where t2.colA = t1.colA
and t2.colB = t1.colB
and t2.id <> t1.id)
另一个技巧是选择具有最小id的不同记录,并保留:
delete T
where id not in
(select min(id) from T
group by colA, colB)
(对不起,我还没有测试过这些,但其中一个想法可能会引导您找到解决方案。)
请注意,如果您没有主键,唯一的另一种方法是利用像ROWID
这样的伪列 - 但我不确定SQL Server 2008是否提供了这个想法
答案 2 :(得分:3)
即使您没有主键,您也可以通过以下代码删除重复数据
delete from (Tablename)
where tablename.%%physloc%%
NOT IN (select MIN(b.%%physloc%%)
from tablename b
group by b.Column1,b.column2,b.column3
);
答案 3 :(得分:0)
假设您有一个名为id的主键,其他列是col2 ... coln,而“重复”行则表示除PK之外的所有列值都重复的所有行
delete from A where id not in
(select min(id) from A
group by col2, col3, ...coln) as x
即。所有非PK列上的小组