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)
只需直接更新子查询:
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)