桌子
Customer
ID | 动作 | 日期 | 时间 |
---|---|---|---|
10 | 优惠 | 26.04.2023 | 15:00 |
10 | 见面 | 25.04.2023 | 14:15 |
10 | 电话 | 24.04.2023 | 13:00 |
10 | 等等 | 23.04.2023 | 12:00 |
201 | 等等 | 15.04.2023 | 14:30 |
201 | 等等 | 15.04.2023 | 13:30 |
201 | 电话 | 15.04.2023 | 12:30 |
201 | 电话 | 15.04.2023 | 11:30 |
201 | 等等 | 15.04.2023 | 10:30 |
3020 | 等等 | 6.10.2021 | 8:00 |
3020 | 等等 | 5.10.2021 | 8:00 |
3020 | 电话 | 2021 年 10 月 4 日 | 8:00 |
3020 | 等等 | 2.10.2021 | 8:00 |
3020 | 等等 | 1.10.2021 | 8:00 |
3020 | 等等 | 1.10.2021 | 8:00 |
我需要找出每个 ID 的等待记录。
连续等待的定义是:
ID
的最新行开始,如果Action
是Wait
则wait-streak = 1ID
的下一个时间顺序的行有Action
= Wait
,等待连胜增加1ID
的所有行按时间顺序循环,如果连胜继续,则等待连胜加 1Wait
有多个条纹,必须找到最大的并且必须保留最新条纹的值除了
Date
,还必须考虑Time
。将这些组合到一个新的日期/时间列中更好,还是有一种使用现有列的简单方法?
在计算之后或期间,结果应更新到新表中。
BiggestWaitStreak
列中发现的最长连胜,NewestWaitStreak
列中的最新连胜,如果最新的 Action
是 Wait
,则 NewestIsWait
列必须设置为 1.
更新后新的统计表应该是这样的:
桌子
ContactStats
ID | BiggestWaitStreak | NewestWaitStreak | NewestIsWait |
---|---|---|---|
10 | 1 | 1 | 0 |
201 | 2 | 2 | 1 |
3020 | 3 | 2 | 1 |
我想实现这一目标的最佳方法是利用 CTE 或临时表。我个人更喜欢 CTE。我很乐意添加我正在进行的工作,但不幸的是没有。我不知道从哪里开始。
非常感谢任何帮助。
这是一个经典的缺口和孤岛问题
查找数据孤岛的经典解决方案是使用
LAG
和/或 LEAD
找到孤岛的开始/结束,然后使用窗口化的 COUNT
为每个部分创建一个 ID。
然后只需使用更多基于该 ID 分配的窗口函数即可。有一个轻微的调整,
NewestIsWait
可以使用 FIRST_VALUE
单独计算。
WITH PrevValues AS (
SELECT *,
PrevAction = LAG(Action) OVER (PARTITION BY ID ORDER BY Date DESC, Time DESC),
NewestIsWait = CASE WHEN
FIRST_VALUE(Action) OVER (PARTITION BY ID ORDER BY Date DESC, Time DESC ROWS UNBOUNDED PRECEDING)
= 'Wait' THEN 1 ELSE 0 END
FROM YourTable
),
Grouped AS (
SELECT *,
GroupId = COUNT(CASE WHEN Action = 'Wait' AND (PrevAction <> 'Wait' OR PrevAction IS NULL) THEN 1 END)
OVER (PARTITION BY ID ORDER BY Date DESC, Time DESC ROWS UNBOUNDED PRECEDING)
FROM PrevValues
),
Counted AS (
SELECT *,
StreakLength = COUNT(CASE WHEN Action = 'Wait' THEN 1 END)
OVER (PARTITION BY ID, GroupId)
FROM Grouped
)
SELECT
ID,
Action,
Date,
Time,
BiggestWaitStreak = MAX(StreakLength) OVER (PARTITION BY ID),
NewestWaitStreak = MIN(CASE WHEN GroupId = 1 THEN StreakLength END) OVER (PARTITION BY ID),
NewestIsWait
FROM Counted;
我建议你考虑将
Date
和Time
列合并为一个。