Oracle GROUP BY结合CASE+SUM/MAX查询报ORA-00979错误咨询
ORA-00979错误排查与修正
首先给出明确结论:GROUP BY分组查询完全支持CASE语句搭配SUM、MAX等聚合函数使用,你遇到的报错是写法逻辑错误导致,并非语法不兼容。
错误原因
你当前的写法存在两个核心问题:
- 执行顺序逻辑冲突:SQL的执行逻辑是先按GROUP BY字段完成分区分组,再对每个分组计算聚合值。你把
SUM()、MAX()聚合函数写在CASE语句的返回分支里,却把行级判断条件PROCESSMASTER.COMP_FLG =1 AND PROCESS.MED_PROC_CD='OUT-P'写在CASE的判断位,相当于要在聚合计算阶段引用未参与分组的行级字段,直接触发Oracle的GROUP BY严格校验规则。 - 字段缺失:SELECT列表中CASE判断用到的
PROCESSMASTER.COMP_FLG没有出现在GROUP BY子句中,完全符合ORA-00979的触发条件——SELECT中非聚合函数包裹的所有字段,必须全部列入GROUP BY列表。
修正方案
把CASE判断逻辑移动到聚合函数内部,先对行做条件判断,再按分组做聚合计算,修正后的SQL如下:
SELECT PLAN.MFGNO "MFGNO", PROCESSMASTER.PART_NO "PART_NO", PROCESS.MED_PROC_CD "M_PROCESS", MAX(PLAN.PLAN_START) "PLAN_START_DATE", MAX(PLAN.PLAN_END) "PLAN_END_DATE", MAX(PLAN.ACT_START) "ACT_START_DATE", MAX(PLAN.ACT_END) "ACT_END_DATE", -- 聚合函数内嵌套CASE,按行判断后再计算分组值 SUM(CASE WHEN PROCESSMASTER.COMP_FLG = 1 AND PROCESS.MED_PROC_CD = 'OUT-P' THEN SUB_PRO.HACYUKIN ELSE 0 END) + MAX(CASE WHEN NOT (PROCESSMASTER.COMP_FLG = 1 AND PROCESS.MED_PROC_CD = 'OUT-P') THEN SUB_PRO.HACYUKIN ELSE NULL END) AS "SUB_TOTAL_PRICE", MAX(SUB_PRO.SICD) "SUB_CODE", MAX(PROCESSMASTER.PROC_REM) "DE_PROCESS" FROM T_PLANDATA PLAN INNER JOIN T_PROCESSNO PROCESSMASTER ON PLAN.BARCODE = PROCESSMASTER.BARCODE INNER JOIN T_PLANNED_PROCESS PROCESS ON PROCESSMASTER.PROCESS_CD = PROCESS.PLAN_PROC_CD INNER JOIN KEIKAKUMST SUB_PRO ON PROCESSMASTER.BARCODE = SUB_PRO.KMSEQNO WHERE PLAN.MFGNO ='T21-F2D1-10034' GROUP BY PLAN.MFGNO, PROCESSMASTER.PART_NO, PROCESS.MED_PROC_CD;
注意事项
- 上述写法完全匹配你原本的业务逻辑:当分组内对应记录满足
COMP_FLG=1且工序编码为OUT-P时,对金额字段求和;其余场景取分组内金额的最大值。 - 如果同一个
MFGNO+PART_NO+MED_PROC_CD分组下,PROCESSMASTER.COMP_FLG同时存在1和0两种值,说明当前GROUP BY的粒度过粗,需要把PROCESSMASTER.COMP_FLG也加入GROUP BY列表,否则计算结果会出现逻辑偏差。 - Oracle采用严格的GROUP BY校验规则,不存在其他数据库的宽松兼容模式,只要SELECT列表中出现未被聚合函数包裹、且未列入GROUP BY的字段,就会直接抛出ORA-00979错误。
内容的提问来源于stack exchange,提问作者Worakrit Rattanasongtham
相关产品推荐
相关产品推荐

