我有这个数据集:
ID | PrevId | NextId | 产品 | 过程 | 日期 |
---|---|---|---|---|---|
1 | NULL | 4 | 产品 1 | 进程A | 2021-04-24 |
2 | NULL | 3 | 产品 2 | 进程A | 2021-04-24 |
3 | 2 | 5 | 产品 2 | 进程A | 2021-04-24 |
4 | 1 | 7 | 产品 1 | 进程B | 2021-04-26 |
5 | 3 | 6 | 产品 2 | 进程B | 2021-04-24 |
6 | 5 | NULL | 产品 2 | 进程B | 2021-04-24 |
7 | 4 | 9 | 产品 1 | 进程B | 2021-04-29 |
9 | 7 | 10 | 产品 1 | 进程A | 2021-05-01 |
10 | 9 | 15 | 产品 1 | 进程A | 2021-05-03 |
15 | 10 | 19 | 产品 1 | 进程A | 2021-05-04 |
19 | 15 | NULL | 产品 1 | 进程C | 2021-05-05 |
每个产品,我需要标记具有相同流程的连续/孤岛记录,例如:
ID | PrevId | NextId | 产品 | 过程 | 日期 | 标签 |
---|---|---|---|---|---|---|
1 | NULL | 4 | 产品 1 | 进程A | 2021-04-24 | 1 |
4 | 1 | 7 | 产品 1 | 进程B | 2021-04-26 | 2 |
7 | 4 | 9 | 产品 1 | 进程B | 2021-04-29 | 2 |
9 | 7 | 10 | 产品 1 | 进程A | 2021-05-01 | 3 |
10 | 9 | 15 | 产品 1 | 进程A | 2021-05-03 | 3 |
15 | 10 | 19 | 产品 1 | 进程A | 2021-05-04 | 3 |
19 | 15 | NULL | 产品 1 | 进程C | 2021-05-05 | 4 |
一个产品要经历多个过程-es,并且可以多次经历同一个过程。
我基本上需要生成Tag列,其背后的逻辑是具有相同流程的连续记录应该组合在一起,但需要注意的是,相同的流程可以出现在下游,但应被视为一个新组。
我已经尝试了基本的窗口函数(ROW_NUMBER
和 DENSE_RANK
),但问题是那些计算在分区内而不是跨分区。
答案 0 :(得分:2)
您可以使用 lag()
来确定值相同的地方。然后累积和:
select t.*,
1 + sum(case when process = prev_process then 0 else 1 end) over (partition by producct order by id) as tag
from (select t.*,
lag(process) over (partition by product order by id) as prev_process
from t
) t;
Here 是一个 db<>fiddle。
答案 1 :(得分:1)
如果您不必验证 prevId 和 nextId(即您的数据已经正确排序),您可以尝试以下操作:
WITH cte AS(
SELECT *
, ROW_NUMBER() OVER (PARTITION BY Product ORDER BY [Date]) x
, DENSE_RANK() OVER (PARTITION BY Product, Process ORDER BY [Date]) y
FROM T1
WHERE product = 'Product 1'
),
cteTag AS(
SELECT Id, PrevId, NextId, Product, Process, [Date], x-y AS Tag_
FROM cte
)
SELECT Id, PrevId, NextId, Product, Process, [Date], DENSE_RANK() OVER (PARTITION BY Product ORDER BY Tag_) AS Tag
FROM cteTag
ORDER BY [Date]