Обнаружение ORA-00979: не выражение GROUP BY при использовании операторов CASE - IN в SQL - PullRequest
2 голосов
/ 29 сентября 2010

Это работает:

 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 ]

2 голосов
/ 29 сентября 2010

Я не могу воспроизвести эту ошибку со следующим запросом (работает):

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 голос
/ 29 сентября 2010

Есть ли причина, по которой вы не можете переместить подвыбор в объединение?Из вашей скорректированной версии на тестовом примере @ 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;

Что дает (в 10 г):

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)
...