2010-09-29 11 views
2

這工作:遭遇ORA-00979:不是GROUP BY表達式中使用CASE時 - 在SQL中的語句

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語句做一個陳述(試圖更加動態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

伯努瓦:這是基於你的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語句中被引用。

+0

什麼版本的Oracle您使用的是? – 2010-09-29 08:08:37

+0

忘記了添加。我們正在使用Oracle 10g – jonasespelita 2010-09-29 08:13:02

+1

您最後的選擇適用於Oracle 11gR2,而不是v9。 – Benoit 2010-09-29 09:10:39

回答

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

有趣。事實上,虛擬測試的作品。我將更多地關注我的選擇並嘗試獲得更準確的虛擬sql。現在爲你祝福,我的好先生。 – jonasespelita 2010-09-29 08:22:57

+0

我忘了說我已經在9.2.0.6.0上的11g版本11.2.0.1.0 64bit AS上進行了測試。 – Benoit 2010-09-29 08:31:14

+0

Benoit,我把一個編輯應該複製我所看到的。謝謝, – jonasespelita 2010-09-29 08:54:58

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; 

其中給出(以10克):

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

並不完全相信,這將使你想要的答案,但很難說是它很簡單,可能是一個起點。


編輯看起來這確實太簡單了。另一種可能的解決方案,看起來也過於簡單,但可能做的伎倆是從另一端接近這一點,才使在 selectcase聚合函數:

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

你的代碼作爲上下文,'b'應該是一個配置表,所以如果我們將子查詢移入連接,我們將得到一個笛卡爾。是的,實際的代碼是複雜的業務邏輯。 – jonasespelita 2010-09-29 09:36:09

+1

@jonasespelita:笛卡爾聯接本質上並不壞。如果第二個選擇總是返回一行,則笛卡爾結果不會超過您編寫的查詢的結果,並且性能應該幾乎相同。 – Allan 2010-09-30 12:39:37

+0

@Allan確實。但是由於在實際製作中,第二個選擇會返回十幾行......你會明白這一點。 :) 謝謝(你的)信息。 – jonasespelita 2010-10-01 19:39:25

相關問題