Относительно группы по - Oracle 10g - PullRequest
0 голосов
/ 14 апреля 2011

Использование Oracle10g. Я использую «случай, когда» в предложении GROUP BY. Проблема в том, когда я использую:

a.book_name IN (SELECT BOOK 
                  FROM BOOK_CONF)

Это говорит, что это не предложение GROUP BY. Кто-нибудь может мне помочь по этому поводу?

  SELECT pub_name, 
         CASE 
           WHEN a.book_name IN (SELECT BOOK FROM BOOK_CONF) THEN 'UNI'   
           WHEN a.book_name ='JAVA' THEN 'JAVA'    
           ELSE 'MIS'    
         END) test, 
         COUNT(*) 
    FROM books a 
GROUP BY pub_name, 
         CASE 
           WHEN a.book_name in (SELECT BOOK FROM BOOK_CONF) THEN 'UNI'
           WHEN a.book_name ='JAVA' THEN 'JAVA'    
         ELSE 'MIS'

Ответы [ 4 ]

3 голосов
/ 14 апреля 2011

Пожалуйста, позвольте мне подвести итог, потому что здесь есть несколько хороших и плохих советов, смешанных вместе.

Сначала ваши таблицы с некоторыми примерами данных:

SQL> create table books (book_name,pub_name)
  2  as
  3  select 'JAVA', 'PUB1' from dual union all
  4  select 'JAVA', 'PUB2' from dual union all
  5  select 'ABC', 'PUB1' from dual union all
  6  select 'XYZ', 'PUB3' from dual union all
  7  select 'KLM', 'PUB3' from dual
  8  /

Table created.

SQL> create table book_conf (book)
  2  as
  3  select 'XYZ' from dual union all
  4  select 'KLM' from dual
  5  /

Table created.

Ваш запрос:

SQL> SELECT pub_name
  2       , CASE
  3         WHEN a.book_name IN (SELECT BOOK FROM BOOK_CONF) THEN
  4           'UNI'
  5         WHEN a.book_name ='JAVA' THEN
  6           'JAVA'
  7         ELSE
  8           'MIS'
  9         END test
 10       , COUNT(*)
 11    FROM books a
 12   GROUP BY pub_name
 13       , CASE
 14         WHEN a.book_name in (SELECT BOOK FROM BOOK_CONF) THEN
 15           'UNI'
 16         WHEN a.book_name ='JAVA' THEN
 17           'JAVA'
 18         ELSE
 19           'MIS'
 20         END
 21  /
       WHEN a.book_name IN (SELECT BOOK FROM BOOK_CONF) THEN
            *
ERROR at line 3:
ORA-00979: not a GROUP BY expression

Это НЕ потому, что выражение CASE недопустимо в выражении group by.Это потому, что вы используете оператор SELECT в вашем предложении GROUP BY.Если вы замените «IN (SELECT book FROM book_conf)» на «IN ('XYZ', 'KLM')", вы увидите, что ваш оператор теперь успешно выполняется:

SQL> SELECT pub_name
  2       , CASE
  3         WHEN a.book_name IN ('XYZ','KLM') THEN
  4           'UNI'
  5         WHEN a.book_name ='JAVA' THEN
  6           'JAVA'
  7         ELSE
  8           'MIS'
  9         END test
 10       , COUNT(*)
 11    FROM books a
 12   GROUP BY pub_name
 13       , CASE
 14         WHEN a.book_name in ('XYZ','KLM') THEN
 15           'UNI'
 16         WHEN a.book_name ='JAVA' THEN
 17           'JAVA'
 18         ELSE
 19           'MIS'
 20         END
 21  /

PUB_ TEST   COUNT(*)
---- ---- ----------
PUB1 MIS           1
PUB1 JAVA          1
PUB2 JAVA          1
PUB3 UNI           2

4 rows selected.

Запрос ниже выглядитотлично, не выдает ошибку, но дает другой результат, потому что теперь вы группируете по book_name вместо вашего выражения CASE:

SQL> select a.pub_name
  2       , (CASE WHEN a.book_name in (SELECT BOOK FROM BOOK_CONF) THEN 'UNI'
  3               WHEN a.book_name ='JAVA' THEN 'JAVA'
  4               ELSE 'MIS'
  5          END) test
  6       , count(*)
  7    from books a
  8   group by a.pub_name
  9       , a.book_name
 10  /

PUB_ TEST   COUNT(*)
---- ---- ----------
PUB1 MIS           1
PUB1 JAVA          1
PUB2 JAVA          1
PUB3 UNI           1
PUB3 UNI           1

5 rows selected.

OMG Ponies использует правильный подход, инкапсулируя группу выражением ввстроенный вид:

SQL> select pub_name
  2       , book_type
  3       , count(*)
  4    from ( select pub_name
  5                , case
  6                  when book_name in (select book from book_conf) then
  7                    'UNI'
  8                  when book_name = 'JAVA' then
  9                    'JAVA'
 10                  else
 11                    'MIS'
 12                  end book_type
 13             from books
 14         )
 15   group by pub_name
 16       , book_type
 17  /

PUB_ BOOK   COUNT(*)
---- ---- ----------
PUB1 MIS           1
PUB1 JAVA          1
PUB2 JAVA          1
PUB3 UNI           2

4 rows selected.

Надеюсь, это поможет.

С уважением,
Роб.

3 голосов
/ 14 апреля 2011

Самый ранний Oracle разрешает ссылаться на псевдонимы столбцов: ORDER BY - в противном случае вы получите ORA-00904: Неверный идентификатор (IME, то есть до 10g и включительно) - не знаю, если он изменился в 11g). Поэтому самый простой способ обеспечить это - использовать производное табличное / встроенное представление:

  SELECT x.pub_name,
         x.test,
         COUNT(*)
    FROM (SELECT a.pub_name, 
                 CASE 
                   WHEN a.book_name IN (SELECT BOOK FROM BOOK_CONF) THEN 'UNI'   
                   WHEN a.book_name ='JAVA' THEN 'JAVA'    
                   ELSE 'MIS'    
                 END AS test
            FROM BOOKS a) x
GROUP BY x.pub_name, x.test
1 голос
/ 14 апреля 2011

Поскольку a.book_name - это то, что вы тестируете внутри корпуса, это то, что вы должны иметь в группе:

select a.pub_name, (CASE WHEN a.book_name in (SELECT BOOK FROM BOOK_CONF) THEN 'UNI'   
                       WHEN a.book_name ='JAVA' THEN 'JAVA'    
                       ELSE 'MIS'    
                  END) test, count(*) 
from books a 
group by a.pub_name, a.book_name
1 голос
/ 14 апреля 2011
select pub_name,
(CASE   WHEN a.book_name in(SELECT BOOK FROM BOOK_CONF) THEN 'UNI'  
 WHEN a.book_name ='JAVA' THEN 'JAVA'    ELSE 'MIS'    END)  AS test,
count(*) from books a group by pub_name, test;

Я полагаю, вы не включили тест в группу по выражению. Дайте мне знать, если это работает

...