Oracle SQL分析函数:按连续日期分组相同qte_min值问题
解决连续日期下相同
qte_min值的分组问题 我懂你现在卡在这儿了——要给连续日期里相同的qte_min值按连续区间分组,而不是把所有相同值都揉进一个组里,试了LEAD/LAG、子查询这些常规操作,非过程化代码就是搞不定对吧?
这个场景其实是SQL里经典的“连续相同值分组”问题,用窗口函数的组合就能搞定,完全不需要过程化代码。下面给你具体的实现思路和示例:
示例输入数据
先假设我们有这样的连续日期数据:
WITH sample_data AS ( SELECT DATE '2024-01-01' AS record_date, 5 AS qte_min UNION ALL SELECT DATE '2024-01-02', 5 UNION ALL SELECT DATE '2024-01-03', 3 UNION ALL SELECT DATE '2024-01-04', 3 UNION ALL SELECT DATE '2024-01-05', 5 UNION ALL SELECT DATE '2024-01-06', 5 UNION ALL SELECT DATE '2024-01-07', 5 )
核心解决方案
我们可以通过“标记分组变化点 + 累加生成分组ID”的思路来实现:
WITH sample_data AS ( SELECT DATE '2024-01-01' AS record_date, 5 AS qte_min UNION ALL SELECT DATE '2024-01-02', 5 UNION ALL SELECT DATE '2024-01-03', 3 UNION ALL SELECT DATE '2024-01-04', 3 UNION ALL SELECT DATE '2024-01-05', 5 UNION ALL SELECT DATE '2024-01-06', 5 UNION ALL SELECT DATE '2024-01-07', 5 ), group_markers AS ( SELECT record_date, qte_min, -- 当当前行qte_min和前一行不同时,标记为1(表示新分组开始),否则为0 CASE WHEN LAG(qte_min) OVER (ORDER BY record_date) != qte_min THEN 1 ELSE 0 END AS group_change FROM sample_data ) SELECT record_date, qte_min, -- 累加group_change值,得到连续相同值的分组ID SUM(group_change) OVER (ORDER BY record_date) + 1 AS group_id FROM group_markers ORDER BY record_date;
输出结果
执行后会得到符合需求的分组结果:
| record_date | qte_min | group_id |
|---|---|---|
| 2024-01-01 | 5 | 1 |
| 2024-01-02 | 5 | 1 |
| 2024-01-03 | 3 | 2 |
| 2024-01-04 | 3 | 2 |
| 2024-01-05 | 5 | 3 |
| 2024-01-06 | 5 | 3 |
| 2024-01-07 | 5 | 3 |
逻辑解释
- 标记分组变化点:用
LAG(qte_min)获取前一行的qte_min值,和当前行对比——如果不一样,说明这是一个新分组的开始,标记为1;否则标记为0。 - 生成分组ID:用
SUM() OVER (ORDER BY record_date)对标记值做累加,每遇到一个1,分组ID就会递增,这样就把连续相同的qte_min分到了同一个组,而不连续的相同值会被分到不同组。
这个方案是纯非过程化的窗口函数实现,支持大多数现代SQL数据库(比如PostgreSQL、MySQL 8+、SQL Server等),如果你的数据库有特殊语法,只需要微调DATE函数或者窗口函数的写法即可。
内容的提问来源于stack exchange,提问作者Pierre Durand
相关产品推荐
相关产品推荐

