Oracle SQL分组用TO_CHAR报ORA-00979错误的排查与解决
问题解决:ORA-00979: not a GROUP BY expression
错误原因
你的SQL中ORDER BY子句使用了原始的sh21.start_time字段,但这个字段既没有出现在GROUP BY列表中,也没有被聚合函数包裹。Oracle的GROUP BY规则要求:SELECT和ORDER BY中的非聚合字段必须存在于GROUP BY子句里——分组后每个组对应多个原始start_time值,Oracle无法确定用哪个值来排序,因此抛出错误。
修正方案
你有两种简单的修正方式:
方案1:使用SELECT中的字段别名排序
直接引用SELECT里格式化后的日期别名start_time排序,这个别名对应的表达式已经在GROUP BY中:
SELECT papf.person_number emp_id, to_char(sh21.start_time,'dd/mm/yyyy') start_time, to_char(sh21.stop_time,'dd/mm/yyyy') stop_time, SUM(sh21.measure) working_hours FROM per_all_people_f papf, hwm_tm_rec sh21 WHERE ... GROUP BY papf.person_number, to_char(sh21.start_time,'dd/mm/yyyy'), to_char(sh21.stop_time,'dd/mm/yyyy') ORDER BY start_time; -- 使用SELECT中定义的别名
方案2:重复GROUP BY中的TO_CHAR表达式排序
在ORDER BY中直接写格式化日期的表达式,和GROUP BY保持一致:
SELECT papf.person_number emp_id, to_char(sh21.start_time,'dd/mm/yyyy') start_time, to_char(sh21.stop_time,'dd/mm/yyyy') stop_time, SUM(sh21.measure) working_hours FROM per_all_people_f papf, hwm_tm_rec sh21 WHERE ... GROUP BY papf.person_number, to_char(sh21.start_time,'dd/mm/yyyy'), to_char(sh21.stop_time,'dd/mm/yyyy') ORDER BY to_char(sh21.start_time,'dd/mm/yyyy'); -- 重复分组时的表达式
额外注意点
如果存在员工的工作记录跨天(start_time和stop_time不在同一天),当前的分组逻辑会把该记录分到两个日期组里。如果你的需求是按实际工作日期统计(比如跨天的工时拆分到对应日期),还需要进一步调整逻辑,但当前方案已经能解决ORA-00979错误并实现按日分组的需求。
内容的提问来源于stack exchange,提问作者Aasem Shoshari
相关产品推荐
相关产品推荐

