2012-07-23 67 views
10

asked this question a while back删除基于列的重复记录。答案很好:我可以删除基于多列的数据库副本吗?

delete from tbl 
where id NOT in 
(
select min(id) 
from tbl 
group by sourceid 
) 

我现在有一个类似的情况,但重复记录的定义是基于多列。如何修改上面的SQL以确定重复的记录,其中唯一记录被定义为从Col1 + Col2 + Col3连接起来。我会做这样的事吗?

delete from tbl 
where id NOT in 
(
select min(id) 
from tbl 
group by col1, col2, col3 
) 
+0

原理仍然存在 - 分组是由一个还是多个列组成并不重要。您将只保留组中的第一行。但是 - 如果您不介意我说 - 在发出删除之前一定要检查您的数据。转换删除选择,看看什么将不会生存。 – 2012-07-23 14:41:52

+0

@Nikola Markovinovic - 它看起来像做正确的事情,但只是想确认 – leora 2012-07-23 15:00:11

+0

@leora我发现你使用的语法繁琐的概念化/逆向工程。它不能很好地转化为id可能为空的情况(因为在不涉及空值的情况下,'not in'的行为不如您预期的那样)。我意识到这不太可能是一个因素,但重要的是要了解有关CTE和不存在的情况下,它可能... – 2012-07-23 15:20:29

回答

23

这表明你想保留的行:

;WITH x AS 
(
    SELECT col1, col2, col3, rn = ROW_NUMBER() OVER 
     (PARTITION BY col1, col2, col3 ORDER BY id) 
    FROM dbo.tbl 
) 
SELECT col1, col2, col3 FROM x WHERE rn = 1; 

这说明你要删除的行:

;WITH x AS 
(
    SELECT col1, col2, col3, rn = ROW_NUMBER() OVER 
     (PARTITION BY col1, col2, col3 ORDER BY id) 
    FROM dbo.tbl 
) 
SELECT col1, col2, col3 FROM x WHERE rn > 1; 

而且一旦你高兴的是,以上两组是正确的,下面实际上会删除它们:

;WITH x AS 
(
    SELECT col1, col2, col3, rn = ROW_NUMBER() OVER 
     (PARTITION BY col1, col2, col3 ORDER BY id) 
    FROM dbo.tbl 
) 
DELETE x WHERE rn > 1; 

请注意,在所有三个查询中,前6行是相同的,只有在CTE后面的后续查询发生了变化。

+0

伟大的解决方案亚伦! – mark1234 2014-06-20 15:17:12

+0

极好的解决方案。 – CheGuevarasBeret 2015-09-17 15:47:18

4

试试这个。 我创建了一个表格tblA有三列。

CREATE TABLE tblA 
(
id int IDENTITY(1, 1), 
colA int, 
colB int, 
colC int 
) 

并添加了一些重复的值。

INSERT INTO tblA VALUES (1, 2, 3) 
INSERT INTO tblA VALUES (1, 2, 3) 
INSERT INTO tblA VALUES (4, 5, 6) 
INSERT INTO tblA VALUES (7, 8, 9) 
INSERT INTO tblA VALUES (7, 8, 9) 

如果在下面的语句中将select替换为delete,那么您的多列删除将起作用。

SELECT MIN(Id) as id 
FROM 
(
SELECT COUNT(*) as aantal, a.colA, a.colB, a.colC 
FROM tblA  a 
INNER JOIN tblA b ON b.ColA = a.ColA 
        AND b.ColB = a.ColB 
        AND b.ColC = a.ColC 
GROUP BY a.id, a.colA, a.colB, a.colC 
HAVING COUNT(*) > 1 
) c 
INNER JOIN tblA d ON d.ColA = c.ColA 
        AND d.ColB = c.ColB 
        AND d.ColC = c.ColC 
GROUP BY d.colA, d.colB, d.colC 
+1

“三角形自动连接”*工程*,但如此笨重...... – ErikE 2012-12-01 02:08:02

相关问题