遇到ORA-00979:在sql中使用CASE-IN语句时不是GROUP BY表达式

时间:2010-09-29 07:53:58

标签: sql oracle plsql ora-00979

这有效:

 SELECT (CASE
             WHEN x = 'value' THEN
              a.col1
             ELSE
              nvl(a.col1, a.col2)
           END)
      FROM table1 a
     WHERE a.this = 'that'
     GROUP BY (CASE
                WHEN x = 'value'  THEN
                 a.col1
                ELSE
                 nvl(a.col1, a.col2)
              END)

但是尝试让case语句执行IN语句(在这里尝试更动态的sql),以下代码会导致 ORA-00979 错误。

SELECT (CASE
         WHEN x IN (SELECT me FROM here WHERE this = 'example') THEN
          a.col1
         ELSE
          nvl(a.col1, a.col2)
       END)
  FROM table1 a
 WHERE a.this = 'that'
 GROUP BY (CASE
            WHEN x IN (SELECT me FROM here WHERE this = 'example') THEN
             a.col1
            ELSE
             nvl(a.col1, a.col2)
          END)

是否有可能完成这项工作或有其他选择?谢谢。 --Jonas

Benoit :这是一个基于你的sql的修改过的sql,它重新创建了错误:

select (case when a.y IN (select 'A'||ROWNUM from dual where rownum=1) then 1 else 0 end)
from (SELECT 'A'||ROWNUM y, 'B' x FROM DUAL CONNECT BY ROWNUM <= 3) a where x = 'B'
group by (case when a.y IN (select 'A'||ROWNUM from dual where rownum=1) then 1 else 0 end)
;

基本上缺少的是FROM表应该有多个值,并且在CASE语句中引用了一列。

2 个答案:

答案 0 :(得分:2)

我无法通过以下请求(工作)重现此错误:

select (case when 'X' IN (select dummy from dual where rownum=1) then 1 else 0 end)
from dual
where dummy = 'X'
group by (case when 'X' IN (select dummy from dual where rownum=1) then 1 else 0 end)
;

尝试:

WITH table1_extended AS (
   SELECT a.*, CASE WHEN x IN .... END "condition"
     FROM table1 a
)
SELECT b."condition"
  FROM table1_extended b
 WHERE b.this = 'that'
 GROUP BY b."condition"

答案 1 :(得分:1)

是否有理由不能将子选项移动到连接中?从@ Benoit的测试用例中调整后的版本中你可以做到:

select case when a.y = b.z then 1 else 0 end, count(*)
from (select 'A'||rownum y, 'B' x from dual connect by rownum <= 3) a,
    (select 'A'||rownum z from dual where rownum=1) b
where a.x = 'B'
group by case when a.y = b.z then 1 else 0 end;

给出(10g):

CASEWHENA.Y=B.ZTHEN1ELSE0END COUNT(*)               
---------------------------- ---------------------- 
1                            1                      
0                            2

并不完全相信会给出你想要的答案,但很难说它是如此简化,可能是一个起点。

<小时/> 编辑似乎这确实太简单了。另一个可能看起来过于简单但可能做到这一点的解决方案是从另一端接近这个,只需将case中的select作为一个聚合函数:

SELECT MIN(CASE
         WHEN x IN (SELECT me FROM here WHERE this = 'example') THEN
          a.col1
         ELSE
          nvl(a.col1, a.col2)
       END)
  FROM table1 a
 WHERE a.this = 'that'
 GROUP BY (CASE
            WHEN x IN (SELECT me FROM here WHERE this = 'example') THEN
             a.col1
            ELSE
             nvl(a.col1, a.col2)
          END)