成对的重复、相同的行。只更新其中一个

Pairs of duplicate, identical rows. Update just one of them

在 SQL-Server 中处理相当大的 table。 Table 有一些相同的行。我需要删除重复的行。问题是我不能改变这个 table 即创建一个 ID 列。

我可以在成对的重复项上更新另一行的一个列值。然后使用这个值删除。

如何只更新这些行中的一个? 例如:首先/最后插入,第一次出现,最新/最旧..

谢谢!

table结构

NrValue |   Comment |   Value1  |   Value2  |   Value3      |
--------|-----------|-----------|-----------|---------------|
00000   |   data0   |   zz      |   top     |   vivalasvegas|
00100   |   NULL    |   N/A     |   sex     |   no          |
00100   |   NULL    |   N/A     |   sex     |   no          |
00200   |   NULL    |   female  |   sex     |   yes         |
00200   |   NULL    |   female  |   sex     |   yes         |
00300   |   NULL    |   male    |   sex     |   yesplease   |
00300   |   NULL    |   male    |   sex     |   yesplease   |
00400   |   data21  |   M       |   --      |   na          |
00500   |   NULL    |   F       |   ezig    |   na          |

所以,我可以使用 'Comment' -column 来更新,但除了重复的行我不能触及。我通过 NrValue 知道哪些行可以更新。 结果将是:

NrValue |   Comment |   Value1  |   Value2  |   Value3      |
--------|-----------|-----------|-----------|---------------|
00000   |   data0   |   zz      |   top     |   vivalasvegas|
00100   |   1       |   N/A     |   sex     |   no          |
00100   |   2       |   N/A     |   sex     |   no          |
00200   |   3       |   female  |   sex     |   yes         |
00200   |   4       |   female  |   sex     |   yes         |
00300   |   5       |   male    |   sex     |   yesplease   |
00300   |   6       |   male    |   sex     |   yesplease   |
00400   |   data21  |   M       |   --      |   na          |
00500   |   NULL    |   F       |   ezig    |   na          |

最后,我删除了 NrValue = 00100、00200 或 00300 AND Comment = 2、4 或 6 的行。

使用类似

的东西
ROW_NUMBER() OVER(PARTITION BY AllRelevantColumns ORDER BY SomeOrderCriteria)

这将为所有行生成 1,但重复项会生成 2(或 3 ...)

您可以将此值放在新列中或将其用于清理...

更新根据您的测试数据...

DECLARE @mockup TABLE(NrValue INT,Comment VARCHAR(100),Value1 VARCHAR(100),Value2 VARCHAR(100),Value3 VARCHAR(100));      
INSERT INTO @mockup  VALUES
 (00000,'data0','zz','top','vivalasvegas')
,(00100,'NULL','N/A','sex','no')
,(00100,'NULL','N/A','sex','no')
,(00200,'NULL','female','sex','yes')
,(00200,'NULL','female','sex','yes')
,(00300,'NULL','male','sex','yesplease')
,(00300,'NULL','male','sex','yesplease')
,(00400,'data21','M','--','na')
,(00500,'NULL','F','ezig','na');

WITH Numbered AS
(
    SELECT ROW_NUMBER() OVER(PARTITION BY NrValue ORDER BY (SELECT NULL)) AS DupNr
          ,*
    FROM @mockup 
)
DELETE FROM Numbered 
WHERE DupNr>1;

SELECT * FROM @mockup;

这个概念称为可更新的 CTEDELETE FROM Numbered ... 实际上会影响基础 table...

如果 NrValue 不足以将一行检测为重复,只需向 PARTITION BY

添加更多列

您不需要更新,您想要删除重复项,那么为什么要进行中间步骤?

您的代码应如下所示:

    declare @t table (col1 int, col2 int);
    insert into @t values
    (1, 1), (1, 1),
    (1, 2), (1, 2),(1, 2), (1, 2),
    (3, 2), (3, 2),(3, 2);

    with cte as
    (
    select *, row_number() over (partition by col1, col2 order by 1/0) rn
    from @t
    )

    delete cte
    where rn > 1;


     select *
     from @t;

抱歉没有在评论中发布(行数限制和代码格式丢失)