基于嵌套CASE语句实现自定义列col12的SQL语法咨询
SQL语句修正:分组查询中新增计算列col12
业务需求
- 查询
scheduledates表时新增计算列col12,规则如下:- 当
phase列的值**既不是'Pros'也不是'SM'**时:计算当前日期(GETDATE())与分组内estart列最小值的月份差,若差值超过36则取值为36; - 当
phase列的值为'Pros'或'SM'时,直接使用col1列的现有值;
- 当
- 查询结果需按
pbs, phase, project_name, scoping_start, col1进行分组。
原错误SQL
SELECT pbs, phase, project_name,scoping_start,col1 ,CASE WHEN phase <> 'Pros' OR phase <> 'SM' THEN (CASE WHEN (DATEDIFF(m, GETDATE() ,MIN(estart)))>36 THEN 36 ELSE (CASE WHEN (DATEDIFF(m, GETDATE() ,MIN(estart)))) ELSE col1 END AS col12 FROM scheduledates GROUP BY pbs, phase, project_name,scoping_start,col1
错误点说明
- 条件逻辑错误:
phase <> 'Pros' OR phase <> 'SM'逻辑永远为真(任何值都不可能同时等于'Pros'和'SM'),应改为phase <> 'Pros' AND phase <> 'SM'; - CASE语法不完整:内层嵌套CASE缺少
END闭合,且存在不必要的多层嵌套; - 外层CASE缺少闭合END:整个
CASE语句未正确收尾。
修正后的SQL
SELECT pbs, phase, project_name, scoping_start, col1, -- 计算col12列 CASE -- 当phase既不是Pros也不是SM时计算月份差 WHEN phase <> 'Pros' AND phase <> 'SM' THEN -- 月份差超过36则取36,否则取实际差值 IIF(DATEDIFF(m, GETDATE(), MIN(estart)) > 36, 36, DATEDIFF(m, GETDATE(), MIN(estart))) -- 其他情况直接用col1的值 ELSE col1 END AS col12 FROM scheduledates GROUP BY pbs, phase, project_name, scoping_start, col1
补充说明
- 使用
IIF函数简化了嵌套CASE的逻辑,让代码更简洁(也可以继续用CASE实现,效果一致); - 确保分组字段和SELECT中的非聚合字段完全匹配,符合SQL分组查询的规则。
内容的提问来源于stack exchange,提问作者Glss1
相关产品推荐
相关产品推荐

