SQL如何按连续相同的Min/Aim/Max三元组对表数据进行分组查询
SQL连续相同三元组分段聚合方案
你要实现的是连续相同Min/Aim/Max三元组的分组统计,属于SQL经典的「岛屿问题」,可通过窗口函数组合实现,具体逻辑如下:
核心实现逻辑
- 先判断当前行和前一行的三元组是否一致,标记新分组的起始点
- 对起始点标记做累加生成唯一分组ID,连续相同三元组的行会拿到相同的分组ID
- 按分组ID聚合,计算对应汇总指标
完整SQL示例
WITH step1 AS ( -- 第一步:对比前一行三元组,标记新分组起始 SELECT *, -- 任意一个字段变化就算新分组开始,标记为1 CASE WHEN Min = LAG(Min) OVER(PARTITION BY Name ORDER BY ActualStartTime) AND Aim = LAG(Aim) OVER(PARTITION BY Name ORDER BY ActualStartTime) AND Max = LAG(Max) OVER(PARTITION BY Name ORDER BY ActualStartTime) THEN 0 ELSE 1 END AS is_new_group FROM 你的表名 ), step2 AS ( -- 第二步:累加标记生成分组ID SELECT *, SUM(is_new_group) OVER(PARTITION BY Name ORDER BY ActualStartTime) AS group_id FROM step1 ) -- 第三步:按分组聚合计算 SELECT Name, MIN(ActualStartTime) AS 指令开始时间, MAX(ActualEndTime) AS 指令结束时间, SUM(FLOW_SUM) AS 总FLOW_SUM, AVG(LIMS_AVG) AS 平均LIMS_AVG, Min, Aim, Max -- 同一个组内这三个值完全相同,可直接取 FROM step2 GROUP BY Name, group_id, Min, Aim, Max ORDER BY 指令开始时间;
效果说明
对你给出的示例数据,最终会输出2行结果:
- 第一组:包含原表1、2行,
FLOW_SUM求和为5884+2170=8054,LIMS_AVG平均为(148+149)/2=148.5 - 第二组:包含原表第3行,数值和原行一致
注意:如果你的业务中不需要按Name分区,删除所有窗口函数里的
PARTITION BY Name即可。
内容的提问来源于stack exchange,提问作者Yusuf Mert
相关产品推荐
相关产品推荐

