You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在CASE语句中使用LISTAGG函数?ORA-00979错误解决

解决ORA-00979错误:CASE语句中正确使用LISTAGG函数

错误原因

ORA-00979的核心问题是:SELECT子句中的EMP.JOB既没有包含在GROUP BY子句中,也没有被聚合函数(如MAX、MIN)包裹。Oracle的GROUP BY规则要求,查询中所有非聚合列必须出现在GROUP BY列表里。

结合你的测试数据,COMM IS NOT NULL的员工均为SALESMAN,原查询的逻辑矛盾在于:按EMPNO分组时每个组仅对应一名员工,此时使用LISTAGG(用于聚合多行数据)并无实际意义,反而因未处理EMP.JOB触发语法错误。

以下是两种符合需求的修正方案:


方案1:保留按员工(EMPNO)分组的逻辑

若你需要对每个COMM不为空的员工,仅当职位为CLERK/SALESMAN时输出其薪资(单条记录场景下LISTAGG等价于直接取薪资,但按你的写法调整),可通过两种方式修复:

方式A:将EMP.JOB加入GROUP BY

select 
    case 
        when EMP.JOB in ('CLERK','SALESMAN') 
            then listagg(DISTINCT EMP.SAL, ';') within group (order by EMP.EMPNO)
    end as sal
from 
    EMP
where 
    EMP.COMM is not null
group by 
    EMP.EMPNO, EMP.JOB

方式B:用聚合函数包裹EMP.JOB

因每个EMPNO对应唯一职位,使用MAX/MIN不影响结果:

select 
    case 
        when MAX(EMP.JOB) in ('CLERK','SALESMAN') 
            then listagg(DISTINCT EMP.SAL, ';') within group (order by EMP.EMPNO)
    end as sal
from 
    EMP
where 
    EMP.COMM is not null
group by 
    EMP.EMPNO

这两种写法都会返回每个符合条件员工的薪资,不符合职位要求的记录返回NULL。


方案2:按职位分组,拼接同职位薪资

若你的真实需求是将COMM不为空的员工中,职位为CLERK/SALESMAN的薪资按职位分组拼接,需调整GROUP BY为JOB:

select 
    EMP.JOB,
    case 
        when EMP.JOB in ('CLERK','SALESMAN') 
            then listagg(DISTINCT EMP.SAL, ';') within group (order by EMP.EMPNO)
    end as sal
from 
    EMP
where 
    EMP.COMM is not null
group by 
    EMP.JOB

根据你的测试数据,该查询会返回SALESMAN对应的去重薪资拼接结果:1600;1250;1500。


内容的提问来源于stack exchange,提问作者Raaj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 06:21:29