基于time_diffs字段条件实现SQL的row_number分组编号
实现基于
time_diffs规则的分组编号逻辑 需求说明
- 当
time_diffs连续为1时,对应行归为同一组 - 当
time_diffs为0时,每行单独成为一组 - 组编号随分组切换依次递增1
解决方案SQL
我们可以通过标记分组起始点+累计求和的方式实现需求,完整SQL如下:
WITH session_with_time_diff AS ( select session_id, player_id, country, start_time, end_time, case when timestampdiff(minute, lag(end_time, 1) over(partition by player_id order by end_time) , start_time) < 5 then 1 when timestampdiff(minute, end_time , lead(start_time, 1) over(partition by player_id order by start_time)) < 5 then 1 else 0 end as time_diffs from game_sessions where player_id = 1 ) SELECT *, SUM(group_start) OVER (PARTITION BY player_id ORDER BY start_time) AS expected_result FROM ( SELECT *, CASE -- 第一行直接作为新分组起始 WHEN lag(time_diffs) OVER (PARTITION BY player_id ORDER BY start_time) IS NULL THEN 1 -- 上一行不是连续1的情况,当前行开启新分组 WHEN lag(time_diffs) OVER (PARTITION BY player_id ORDER BY start_time) != 1 THEN 1 -- 当前行time_diffs为0,单独成组 WHEN time_diffs = 0 THEN 1 -- 其余情况属于当前分组,不触发新分组 ELSE 0 END AS group_start FROM session_with_time_diff ) t ORDER BY player_id, start_time;
逻辑解释
- CTE预处理:保留原查询的
time_diffs计算结果,简化后续逻辑 - 标记分组起始点:
- 第一行无前置行,直接标记为新分组起始
- 如果上一行的
time_diffs不是1,说明当前行是新分组的开始 - 只要当前行
time_diffs为0,无论前置行状态,都单独成组
- 生成组编号:对标记的起始点做累计求和,得到连续递增的组编号,完全匹配需求规则
结果对比
原查询结果
| session_id | player_id | country | start_time | end_time | time_diffs |
|---|---|---|---|---|---|
| 1 | 1 | UK | 01.01.2021 00:01 | 01.01.2021 00:10 | 1 |
| 2 | 1 | UK | 01.01.2021 00:12 | 01.01.2021 01:24 | 1 |
| 13 | 1 | UK | 01.01.2021 01:27 | 01.01.2021 01:50 | 1 |
| 3 | 1 | UK | 01.01.2021 10:01 | 01.01.2021 15:10 | 0 |
| 16 | 1 | UK | 01.01.2021 17:10 | 01.01.2021 17:20 | 1 |
| 17 | 1 | UK | 01.01.2021 17:22 | 01.01.2021 17:55 | 1 |
| 54 | 1 | UK | 01.01.2021 18:15 | 01.01.2021 18:35 | 0 |
| 32 | 1 | UK | 01.01.2021 18:55 | 01.01.2021 19:35 | 0 |
修改后查询结果(符合期望)
| session_id | player_id | country | start_time | end_time | time_diffs | expected_result |
|---|---|---|---|---|---|---|
| 1 | 1 | UK | 01.01.2021 00:01 | 01.01.2021 00:10 | 1 | 1 |
| 2 | 1 | UK | 01.01.2021 00:12 | 01.01.2021 01:24 | 1 | 1 |
| 13 | 1 | UK | 01.01.2021 01:27 | 01.01.2021 01:50 | 1 | 1 |
| 3 | 1 | UK | 01.01.2021 10:01 | 01.01.2021 15:10 | 0 | 2 |
| 16 | 1 | UK | 01.01.2021 17:10 | 01.01.2021 17:20 | 1 | 3 |
| 17 | 1 | UK | 01.01.2021 17:22 | 01.01.2021 17:55 | 1 | 3 |
| 54 | 1 | UK | 01.01.2021 18:15 | 01.01.2021 18:35 | 0 | 4 |
| 32 | 1 | UK | 01.01.2021 18:55 | 01.01.2021 19:35 | 0 | 5 |
内容的提问来源于stack exchange,提问作者bombom
相关产品推荐
相关产品推荐

