关于group by - Oracle 10g

时间:2011-04-14 01:57:59

标签: sql oracle oracle10g aggregate-functions

使用Oracle10g。我在GROUP BY子句中使用“case when”。问题是我使用时:

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 个答案:

答案 0 :(得分:3)

最早的Oracle允许引用列别名是ORDER BY - 否则你将得到ORA-00904:无效的标识符(IME即,如果在11g中发生变化,最高可达10g - dunno)。因此,容纳它的最简单方法是使用派生表/内联视图:

  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 :(得分:3)

请允许我总结一下,因为这里有一些好的和一些不好的建议。

首先是包含一些示例数据的表格:

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

这不是因为group by子句中不允许使用CASE表达式。这是因为您在GROUP BY子句中使用SELECT语句。如果将“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.

希望这有帮助。

的问候,
罗布。

答案 2 :(得分:1)

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;

我相信你没有在group by子句中包含test。如果有效,请告诉我

答案 3 :(得分:1)

由于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