2011-04-14 51 views
0

使用Oracle10g。我在GROUP BY子句中使用“case when”。问题是当我使用:关于group by - Oracle 10g

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' 

回答

3

最早的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 
+0

非常感谢您的信息。我试图运行第二个。它给我“ORA-00979:不是GROUP BY表达式”,并突出显示a.book_name。 – Arav 2011-04-14 04:26:22

+0

@Arav:它在10g-XE上适用于我,这就是为什么我首先提出派生表/内联视图的原因。 – 2011-04-14 04:41:00

+0

仅供参考:11g不允许别人使用别名。 – MacAnthony 2011-04-14 05:13:07

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子句中的测试。让我知道是否可行

+0

在10g-XE上测试,不起作用:'ORA-00904:“测试”无效标识符“。 IME,9i和10g就是这种情况 - 不能在Oracle的GROUP BY中使用列别名 - ORDER BY是最早可以使用Oracle的列别名。 – 2011-04-14 02:15:18

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 
+0

+1:在10g-XE上确认此查询将无错执行。更大的问题是它是否会返回预期的结果。 – 2011-04-14 02:16:40

+0

结果可能并非完全如预期。我只用一个实际的有限情况进行了测试。 – MacAnthony 2011-04-14 02:18:56

+0

非常感谢您的信息。 – Arav 2011-04-14 04:27:09

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 

这并不是因为CASE表达式是不是group by子句允许的。这是因为您在GROUP BY子句中使用了SELECT语句。如果换成“IN(SELECT本书从book_conf)”改为“IN(‘XYZ’,‘荷航’)”,你会看到你的语句现在成功:

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小马在内嵌视图通过表达封装组使用正确的方法:

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. 

希望这有助于。

Regards,
Rob。

+0

非常感谢您的时间。如果你用“IN('XYZ','KLM')”替换“IN(从book_conf中选择书)”,你会发现你的语句现在成功了。我不能因为我可能有1000条记录。所以内联视图对我来说是个解决方案 – Arav 2011-04-15 01:16:45

+0

我的意思是用这个查询来证明一个由CASE表达式组成的组合,并不能说服你硬编码你的book_conf值。 – 2011-04-15 07:31:59