我需要在数据表中设置一个非唯一标识符。这将是一个组内的顺序即。对于每个组,ID应从1开始,并以1的增量上升,直到该组的最后一行。
下表说明了这一点。 “新ID”是我需要填充的列。
Unique ID Group ID New ID
--------- -------- ------
1 1123 1
2 1123 2
3 1124 1
4 1125 1
5 1125 2
6 1125 3
7 1125 4
有没有办法在没有循环/光标的情况下这样做?如果循环/光标是唯一的方法,最有效的代码是什么?
由于
答案 0 :(得分:6)
一种方法是在ROW_NUMBER() OVER(PARTITION BY ... ORDER BY ...)
语句中使用UPDATE...FROM
subquery
中FROM clause
。
update MyTable set NewID = B.NewID
from
MyTable as A
inner join (select UniqueID, ROW_NUMBER() over (partition by GroupID order by UniqueID) as NewID from MyTable) as B on B.UniqueID = A.UniqueID
答案 1 :(得分:4)
我同意Damien在评论中的观点,但您不需要JOIN
,您可以直接更新CTE。
;WITH cte AS
(
SELECT [New ID],
ROW_NUMBER() OVER (PARTITION BY [Group ID] ORDER BY [Unique ID]) AS _NewID
FROM @T
)
UPDATE cte
SET [New ID] = _NewID
答案 2 :(得分:0)
SELECT
UniqueId,
GroupID,
ROW_NUMBER() OVER (PARTITION BY GroupId ORDER BY UniqueId) AS NewIdx
FROM
....
答案 3 :(得分:0)
如果您运行旧版本的mssql
,此解决方案也可以使用--Test table:
DECLARE @t table(Unique_ID int, Group_ID int, New_ID int)
--Test data:
INSERT @t (unique_id, group_id)
SELECT 1, 1123 UNION ALL SELECT 2, 1123 UNION ALL SELECT 3, 1124 UNION ALL SELECT 4, 1125 UNION ALL SELECT 5, 1125 UNION ALL SELECT 6, 1125 UNION ALL SELECT 7, 1125
--Syntax:
UPDATE t
SET new_id =
(SELECT count(*)
FROM @t
WHERE t.unique_id >= unique_id and t.group_id = group_id
GROUP BY group_id)
FROM @t t
--Result:
SELECT * FROM @t
Unique_ID Group_ID New_ID
----------- ----------- -----------
1 1123 1
2 1123 2
3 1124 1
4 1125 1
5 1125 2
6 1125 3
7 1125 4
答案 4 :(得分:0)
如果您使用SS 2000
,则替代行号()SELECT UniqueID,
GroupID,
(SELECT COUNT(T2.GroupID)
FROM myTable T2
WHERE GroupID <= T1.GroupID) AS NewID
FROM myTable T1