如何删除SQL Server 2008中的重复行?

Gol*_*old 3 sql-server-2008

如何在SQL Server 2008中删除重复的行?

Gra*_*ger 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;
Run Code Online (Sandbox Code Playgroud)

您可以在"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');
Run Code Online (Sandbox Code Playgroud)

在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;
Run Code Online (Sandbox Code Playgroud)

现在运行以下查询以删除重复项,从每组重复项中留下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;
Run Code Online (Sandbox Code Playgroud)

您现在剩下5行,其中没有一行是重复的.