TLDNR :如何根据列更新表?
问题情况:当前列SortingNumber
充满了不良数据。
解决方案:根据SortingNumber
将新值重新分配给Parent
。对于最低的当前SortingNumber
(按SortingNumber
),Parent
应当为1,对于随后的每个数据集,该值应递增1。
Current data: Desired result:
ID | Parent | SortingNumber >> ID | Parent | SortingNumber
1 | 1 | 3 >> 1 | 1 | 1
2 | 1 | 4 >> 2 | 1 | 2
3 | 1 | 5 >> 3 | 1 | 3
4 | 2 | 8 >> 4 | 2 | 1
5 | 2 | 10 >> 5 | 2 | 2
6 | 2 | 13 >> 6 | 2 | 3
实际问题:我在弄清楚如何更新与其父代相对应的数据集时遇到了麻烦。
我的脚本当前以增量方式更新所有值,并且未按Parent
对其进行分组。
我当前的解决方案:
DECLARE @lastSN INTEGER = 0;
WITH toUpdate AS
(
SELECT
T1.*,
-- "calculate" the sorting number from the row above
LAG(T1.SortingNumber + 1, 1, 1) OVER (ORDER BY T1.SortingNumber) AS [newSortNumber]
FROM
T AS T1
INNER JOIN
T AS T2 ON T1.Parent = T2.ID
)
UPDATE toUpdate
SET
@lastSN = CASE WHEN [newSortNumber] = 1 AND @lastSN = 0 THEN 1 ELSE @lastSN + 1 END,
toUpdate.SortingNumber = @lastSN
;
结果是:
ID | Parent | SortingNumber
1 | 1 | 1
2 | 1 | 2
3 | 1 | 3
4 | 2 | 4
5 | 2 | 5
6 | 2 | 6
我想我的问题可以表述为:如何根据Parent
列更新数据集?
PS :如果您想自己尝试一下,这里是CREATE
语句
CREATE TABLE T
(
ID INT IDENTITY(1,1) PRIMARY KEY,
Parent INT FOREIGN KEY REFERENCES T(ID),
SortingNumber INT
);
GO
INSERT INTO T (Parent, SortingNumber)
VALUES (1, 3), (1, 4), (1, 5), (2, 8), (2, 10), (2, 13);
答案 0 :(得分:1)
您可以使用row_number
通过Parent
分区和SortingNumber
排序来实现此目的。
WITH cte AS (
SELECT
* ,
ROW_NUMBER() OVER (PARTITION BY Parent ORDER BY SortingNumber) AS NewSortingNumber
FROM T
)
UPDATE cte
SET SortingNumber = NewSortingNumber
窗口函数使用父级在表内创建小表,因此我们有两个子集,一个子集用于Parent = 1,另一个子集用于Parent =2。然后它使用ORDER BY
来知道应该从哪一行开始计数(从1开始)。第一行是针对Parent = 1和ID = 1的,因此它得到1,下一行得到2,依此类推。请在此处查看更多details。
答案 1 :(得分:-1)
作为替代方案,您可以按照患者的身份和ID排序:
UPDATE tt
SET sortingnumber = drank from (select *, DENSE_RANK() OVER (order by Parent, ID) as drank from tt ) a where tt.ID=a.id and tt.parent=a.parent
select * from tt