我有一张表,需要设置两个Flag1
和Flag2
标志值之一。
Create Table StackUpdateTable
(Id Int, GroupId Int, Flag1 Bit, Flag2 Bit, Requirements Int)
现在,这是规则:
Requirements
将是 1或 2。Requirements
指定必须先设置的Flag1
值的数量,然后才能按Flag2
的顺序为给定的GroupId
设置Id
值(上升)。 Flag2
,序列将重新开始(对于每个GroupId
)如果有一种方法可以对此表(以及所有新出现的表)进行基于集合的更新,并且可以为每组GroupId
记录设置标志,那么我一直在想尽办法
为进一步说明,请考虑以下数据:
Insert Into StackUpdateTable Values
(1, 100, 0, 0, 1)
,(2, 100, 0, 0, 1)
,(3, 101, 0, 0, 1)
,(4, 102, 0, 0, 2)
,(5, 102, 0, 0, 2)
,(6, 102, 0, 0, 2)
,(7, 103, 1, 0, 1)
,(8, 103, 0, 0, 1)
,(9, 103, 0, 0, 1)
,(10,104, 1, 0, 2)
,(11,105, 1, 0, 2)
,(12,106, 0, 0, 2)
,(13,106, 0, 0, 2)
,(14,106, 0, 0, 2)
,(15,106, 0, 0, 2)
;
鉴于此数据,这就是生成的更新后的数据的样子
1 100 1 0 1 <-- Flag1 Set
2 100 0 1 1 <-- Flag2 Set
3 101 1 0 1 <-- Flag1 Set
4 102 1 0 2 <-- 1st Flag1 Set
5 102 1 0 2 <-- 2nd Flag1 Set
6 102 0 1 2 <-- Flag2 Set
7 103 1 0 1 <-- Unchanged
8 103 0 1 1 <-- Flag2 Set
9 103 1 0 1 <-- Flag1 Set
10 104 1 0 2 <-- Unchanged
11 104 1 0 2 <-- Unchanged
12 106 1 0 2 <-- 1st Flag1 Set
13 106 1 0 2 <-- 2nd Flag1 Set
14 106 0 1 2 <-- Flag2 Set
15 106 1 0 2 <-- 1st Flag1 Set
如果添加更多数据,那么...
Insert Into StackUpdateTable Values
(16,100, 0, 0, 1)
,(17,103, 0, 0, 1)
,(18,106, 0, 0, 2)
;
...然后更新的数据集(按GroupId
\ Id
顺序应如下所示:
1 100 1 0 1 <-- Unchanged
2 100 0 1 1 <-- Unchanged
16 100 1 0 1 <-- Flag1 Set
3 101 1 0 1 <-- Unchanged
4 102 1 0 2 <-- Unchanged
5 102 1 0 2 <-- Unchanged
6 102 0 1 2 <-- Unchanged
7 103 1 0 1 <-- Unchanged
8 103 0 1 1 <-- Unchanged
9 103 1 0 1 <-- Unchanged
17 103 0 1 1 <-- Flag2 Set
10 104 1 0 2 <-- Unchanged
11 104 1 0 2 <-- Unchanged
12 106 1 0 2 <-- Unchanged
13 106 1 0 2 <-- Unchanged
14 106 0 1 2 <-- Unchanged
15 106 1 0 2 <-- Unchanged
18 106 1 0 2 <-- Flag1 Set
最后,如果应插入以下行:
Insert Into StackUpdateTable Values
(19,106, 0, 0, 2)
;
然后我期望:
1 100 1 0 1 <-- Unchanged
2 100 0 1 1 <-- Unchanged
16 100 1 0 1 <-- Flag1 Set
3 101 1 0 1 <-- Unchanged
4 102 1 0 2 <-- Unchanged
5 102 1 0 2 <-- Unchanged
6 102 0 1 2 <-- Unchanged
7 103 1 0 1 <-- Unchanged
8 103 0 1 1 <-- Unchanged
9 103 1 0 1 <-- Unchanged
17 103 0 1 1 <-- Flag2 Set
10 104 1 0 2 <-- Unchanged
11 104 1 0 2 <-- Unchanged
12 106 1 0 2 <-- Unchanged
13 106 1 0 2 <-- Unchanged
14 106 0 1 2 <-- Unchanged
15 106 1 0 2 <-- Unchanged
18 106 1 0 2 <-- Flag1 Set
19 106 0 1 2 <-- Flag2 Set
我一直在使用诸如Row_Number() Over (Partition By GroupId Order By Id) As _seq
之类的Windowing函数来整理数据,然后再使用几个Lag
函数Lag(Flag1, 1, 0) Over (Partition By GroupId Order By Id) As _Calc1
等,但我却想尝试处理新记录(值以零开头)。
我认为我也需要开始进行记录计数,但是不确定如何处理-认为我也许可以用_seq
做某事,但仍然无处可做。
我想要的是找出每次解析该表时如何执行基于Set的更新。不一定要进行单个更新,实际上我很乐意在组合中删除Temp表,CTE或其他任何东西。我不想要做的一件事就是必须通过Id
或GroupId
来浏览我的方式。
我很愿意听到我的要求无法完成,但是我充满希望!
答案 0 :(得分:1)
使用注释中的ZLK查询,将其转换为UPDATE
语句,每次将记录添加到表后即可运行。
UPDATE s
SET s.Flag1 = CASE WHEN t.RN > 0 THEN 1 ELSE 0 END
,s.Flag2 = CASE WHEN t.RN = 0 THEN 1 ELSE 0 END
FROM
(
SELECT
*
,RN = ROW_NUMBER() OVER ( PARTITION BY GroupID, Requirements ORDER BY ID ) % ( Requirements + 1 )
FROM StackUpdateTable
) T
INNER JOIN StackUpdateTable s ON s.Id = T.Id