如何解决Oracle错误ORA-00979: 非GROUP BY表达式问题
解决ORA-00979: not a GROUP BY expression错误
这个报错的核心原因很明确——Oracle对GROUP BY的语法规则要求很严格:所有出现在SELECT列表中的非聚合函数列,必须同时出现在GROUP BY子句里。
看你的代码,SELECT语句里包含了job_title这个列,但GROUP BY里只指定了to_char(hire_date,'YYYY'),这就违反了规则:Oracle不知道该如何为每个年份分组匹配对应的职位(毕竟同一年份可能有多个不同职位的员工),所以抛出了ORA-00979错误。
根据你的业务需求,有两种解决方案:
方案1:去掉不需要的job_title列(推荐,因为你的输出没用到它)
既然你的PL/SQL块最后输出时根本没用到job_title,说明这个列是多余的,直接从SELECT里移除即可,这样GROUP BY的结构就完全合法了:
DECLARE CURSOR TAMPILDATA IS SELECT TO_CHAR(hire_date,'YYYY') AS thn, COUNT(TO_CHAR(hire_date,'YYYY')) AS jumlah FROM employees a, jobs b WHERE a.job_id = b.job_id GROUP BY TO_CHAR(hire_date,'YYYY') ORDER BY TO_CHAR(hire_date,'YYYY'); BEGIN FOR VARIABLE_X IN TAMPILDATA LOOP DBMS_OUTPUT.PUT_LINE (VARIABLE_X.thn||' : ' ||VARIABLE_X.JUMLAH||' Orang'); END LOOP; END;
方案2:如果需要按「年份+职位」分组统计
如果你的实际需求是要统计每个年份下不同职位的员工数量,那就要把job_title也加入GROUP BY子句,同时可以在输出里加上职位信息让结果更清晰(另外建议用ANSI JOIN语法替代旧的逗号连接,可读性更强):
DECLARE CURSOR TAMPILDATA IS SELECT TO_CHAR(hire_date,'YYYY') AS thn, COUNT(*) AS jumlah, -- 用COUNT(*)更简洁,和COUNT(TO_CHAR(...))效果一致 job_title FROM employees a JOIN jobs b ON a.job_id = b.job_id GROUP BY TO_CHAR(hire_date,'YYYY'), job_title ORDER BY TO_CHAR(hire_date,'YYYY'), job_title; BEGIN FOR VARIABLE_X IN TAMPILDATA LOOP DBMS_OUTPUT.PUT_LINE (VARIABLE_X.thn||' - '||VARIABLE_X.job_title||' : ' ||VARIABLE_X.JUMLAH||' Orang'); END LOOP; END;
内容的提问来源于stack exchange,提问作者Yonathan Rizky




