重命名重复的行

Jak*_*ade 7 t-sql sql-server-2005 common-table-expression sql-update

这是我的问题的简化示例.我有一个表,其中有一个带有重复条目的"名称"列:

ID    Name
---   ----
 1    AAA
 2    AAA
 3    AAA
 4    BBB
 5    CCC
 6    CCC
 7    DDD
 8    DDD
 9    DDD
10    DDD
Run Code Online (Sandbox Code Playgroud)

像这样做的SELECT Name, COUNT(*) AS [Count] FROM Table GROUP BY Name结果如下:

Name  Count
----  -----
AAA   3
BBB   1
CCC   2
DDD   4
Run Code Online (Sandbox Code Playgroud)

我只关心重复项,所以我将添加一个HAVING子句,SELECT Name, COUNT(*) AS [Count] FROM Table GROUP BY Name HAVING COUNT(*) > 1:

Name  Count
----  -----
AAA   3
CCC   2
DDD   4
Run Code Online (Sandbox Code Playgroud)

到目前为止琐碎,但现在事情变得棘手:我需要一个查询来获取所有重复记录,但在Name列中添加了一个很好的递增指示符.结果应如下所示:

ID    Name
---   --------
 1    AAA
 2    AAA (2)
 3    AAA (3)
 5    CCC 
 6    CCC (2)
 7    DDD 
 8    DDD (2)
 9    DDD (3)
10    DDD (4)
Run Code Online (Sandbox Code Playgroud)

注意排除第4行"BBB",第一个副本保留原始名称.

使用EXISTS语句为我提供了我需要的所有记录,但是如何创建新的Name值呢?

SELECT * FROM Table AS T1 
WHERE EXISTS (
    SELECT Name, COUNT(*) AS [Count] 
    FROM Table 
    GROUP BY Name 
    HAVING (COUNT(*) > 1) AND (Name = T1.Name))
ORDER BY Name
Run Code Online (Sandbox Code Playgroud)

我需要创建一个UPDATE语句来修复所有重复项,即根据此模式更改名称.

更新:现在想出来.这是我失踪的PARTITION BY条款.

Tho*_*mas 13

With Dups As
    (
    Select Id, Name
        , Row_Number() Over ( Partition By Name Order By Id ) As Rnk
    From Table
    )
Select D.Id
    , D.Name + Case
                When D.Rnk > 1 Then ' (' + Cast(D.Rnk As varchar(10)) + ')'
                Else ''
                End As Name
From Dups As D
Run Code Online (Sandbox Code Playgroud)

如果你想要一个更新语句,你可以使用几乎相同的结构:

With Dups As
    (
    Select Id, Name
        , Row_Number() Over ( Partition By Name Order By Id ) As Rnk
    From Table
    )
Update Table
Set Name = T.Name + Case
                    When D.Rnk > 1 Then ' (' + Cast(D.Rnk As varchar(10)) + ')'
                    Else ''
                    End
From Table As T
    Join Dups As D
        On D.Id = T.Id
Run Code Online (Sandbox Code Playgroud)


Nat*_*erl 6

只需直接更新子查询:

update d
set Name = Name+'('+cast(r as varchar(10))+')'
from    (   select  Name, 
                    row_number() over (partition by Name order by Name) as r
            from    [table]
        ) d
where r > 1
Run Code Online (Sandbox Code Playgroud)