基于ID与Value列的连续相同值分组编号实现技术问询
解决ID连续且Value相同的行组分配唯一run_id的问题
咱们先理清楚这个需求的本质:这是典型的连续相同值分组(俗称“岛屿问题”)——要把「ID连续且Value相同」的行归为同一组,每组分配唯一的run_id。你之前的代码逻辑过于复杂,依赖多阶LAG的判断很容易遗漏场景,这里给你一个更简洁可靠的方案。
核心思路
要生成唯一的run_id,关键是先找到每个分组的起始行:
- 第一行(没有前一行)肯定是新组的开始
- 当前行的Value和前一行不同 → 新组开始
- 当前行的ID和前一行的ID不连续(即前一行ID + 1 ≠ 当前ID)→ 哪怕Value相同,也是新组开始
然后对这些“起始行标记”做累加,就能得到每个行对应的run_id——因为每遇到一个起始行,累加值就会+1,同一组内的非起始行会保持累加值不变。
完整SQL实现
SELECT id, value, SUM(is_new_group) OVER (ORDER BY id) AS run_id FROM ( SELECT id, value, -- 标记当前行是否是新组的起始行 CASE WHEN LAG(id) OVER (ORDER BY id) IS NULL THEN 1 -- 第一行 WHEN LAG(value) OVER (ORDER BY id) != value THEN 1 -- Value不同 WHEN LAG(id) OVER (ORDER BY id) != id - 1 THEN 1 -- ID不连续 ELSE 0 END AS is_new_group FROM entries ) AS group_markers ORDER BY id;
验证你的示例数据
用你给出的示例表测试,结果会完全符合预期:
| id | value | run_id |
|---|---|---|
| 1 | 7 | 1 |
| 2 | 7 | 1 |
| 3 | 0 | 2 |
| 5 | 0 | 3 |
| 6 | -5 | 4 |
| 7 | 7 | 5 |
| 8 | 7 | 5 |
| 9 | 7 | 5 |
为什么这个方案更好?
- 逻辑清晰:从“识别新组起始”到“累加生成run_id”,每一步都直观,不容易出错
- 性能更优:只需要一次
LAG窗口函数计算,避免了多层嵌套和多阶LAG的冗余计算 - 通用性强:不管分组长度是多少,或者ID断档多少次,都能正确识别分组
内容的提问来源于stack exchange,提问作者Deep Kalra
相关产品推荐
相关产品推荐

