如何为SQL多分组查询结果添加IsLast标志列?
实现带IsLast标志的SQL查询
你的思路完全正确,我们可以通过多层窗口函数逐步实现这个需求,不需要额外的子查询或临时表,直接在原查询基础上扩展即可。
具体实现逻辑拆解
我们分三层来构建判断条件:
- 第一层:计算每个
WorktypeWorkID子组的最大LevelID,记为max_level - 第二层:在每个
WorkTypeId分组内,找到所有max_level中的最小值,记为min_max_level - 第三层:给每个
WorkTypeId下满足max_level = min_max_level的WorktypeWorkID排序,标记出第一个符合条件的子组
完整SQL代码
SELECT WorkTypeId, WorktypeWorkID, LevelID, -- 最终判断IsLast:当前行属于首个符合条件的子组时返回true CASE WHEN group_rank = 1 THEN 'true' ELSE 'false' END AS IsLast FROM ( SELECT *, -- 给每个WorkTypeId下的子组排序:符合条件的子组优先,再按WorktypeWorkID排序 ROW_NUMBER() OVER ( PARTITION BY WorkTypeId ORDER BY CASE WHEN max_level = min_max_level THEN 0 ELSE 1 END, WorktypeWorkID ) AS group_rank FROM ( SELECT w.WorkTypeId, ww.WorktypeWorkID, wwl.LevelID, -- 计算每个WorktypeWorkID的最大LevelID MAX(wwl.LevelID) OVER (PARTITION BY ww.WorktypeWorkID) AS max_level, -- 计算每个WorkTypeId下所有max_level的最小值 MIN(MAX(wwl.LevelID) OVER (PARTITION BY ww.WorktypeWorkID)) OVER (PARTITION BY w.WorkTypeId) AS min_max_level FROM Worktypes as w LEFT JOIN WorktypesWorks as ww on w.ID = ww.WorktypeID LEFT JOIN WorktypesWorksLevels as wwl on ww.ID = wwl.WorktypeWorkID ) AS sub_query1 ) AS sub_query2 ORDER BY WorkTypeId, WorktypeWorkID, LevelID;
结果验证
这个查询会完全匹配你期望的输出:
- 对于
WorkTypeId=1:所有子组的max_level为3、3、1、2、1,min_max_level是1。符合条件的子组是3和5,其中3是第一个,所以它的所有行IsLast为true,其余为false - 对于
WorkTypeId=4:子组的max_level是1、3,min_max_level是1,只有WorktypeWorkID=6符合,所以它的行IsLast为true
补充说明
- 窗口函数的嵌套是核心:内层窗口计算子组最大值,外层窗口计算分组内的最小值,最后通过排序标记首个符合条件的子组
ROW_NUMBER()的排序逻辑确保了我们优先选中符合条件的子组,再按WorktypeWorkID顺序取第一个,完全符合需求中的“首个符合此条件的子组”要求
内容的提问来源于stack exchange,提问作者markzzz
相关产品推荐
相关产品推荐

