2009-09-25 53 views
0

我正在選擇一些聚合數據和日期和特定字段上的分組。我想顯示該字段中的所有值,並計算這些值,即使當天沒有與該字段匹配的數據。例如。在Oracle中刪除額外的子查詢,選擇值的數組

Date  MyField Count 
2009-09-25 A  2 
2009-09-25 B  0 
2009-09-24 A  1 
2009-09-24 B  1 

Oracle的SQL我現在要做的,這是類似以下內容:

SELECT today, 
     mytable.myfield, 
     COUNT(
     CASE WHEN fields.myfield = mytable.myfield AND 
        date >= today AND 
        date < tomorrow 
       THEN 1 
     END 
     ) 
FROM (
     SELECT TRUNC(SYSDATE) + 1 - LEVEL AS today, 
       TRUNC(SYSDATE) + 2 - LEVEL AS tomorrow 
     FROM DUAL 
     CONNECT BY LEVEL <= 30 
    ), 
    (
     /* This is the part that seems inefficient */ 
     SELECT DISTINCT myfield 
     FROM mytable 
     WHERE myfield IN ('A', 'B') 
    ) fields, 
    mytable 
GROUP BY today, mytable.myfield 
ORDER BY today DESC, mytable.myfield ASC 

我擔心的是,我確切地知道哪些值我想顯示myfield,似乎效率不高有一個SELECT查詢訪問mytable。我在想,如果有一些方法我可以做這樣的事情在該子查詢:

SELECT ('A', 'B') AS myfield 
FROM DUAL 

我使用Oracle的較早版本,其中WITH條款不工作。

+0

你使用什麼Oracle版本?按級別連接在Oracle 8中不起作用,因此您使用Oracle 9或10.但Oracle 9和10具有with子句,因此您應該能夠使用with子句。 – tuinstoel 2009-09-26 07:36:38

+0

CONNECT BY LEVEL絕對有效,但WITH子句在我用來訪問我公司的數據庫的接口中沒有工作。我不確定它是什麼版本的Oracle。 – 2009-09-26 16:39:40

+0

從v $版本中選擇*來查看您使用的是哪種Oracle版本。 – tuinstoel 2009-09-26 17:08:44

回答

1

你將不得不把他們作爲不同的行,而不是不同的列。所以,你會

select 'A' from dual 
union 
select 'B' from dual 

在這種情況下結束,查詢應該是等價的,只要有在mytable行與字段「A」和「B」。如果沒有,那麼你的子查詢將返回原來的子查詢不會的行。

0

爲什麼不升級您的Oracle版本? with-clause將首先添加到Oracle 9.2(2002)。你還在使用Oracle 8嗎?

0

您不必領域的子查詢和MYTABLE之間的連接,所以你的結果集將包含一排MyField的每一個價值在過去的三十天。

但是,不是添加該連接,爲什麼不溝通子查詢,只是過濾MYTABLE.MYFIELD?另外,如果您擔心性能問題,則應該在WHERE子句中約束日期,否則您將處理MYTABLE中的每一行。

select today 
     , myfield 
     , count (case when trunc(somedate) = today then 1 end) as ab_count 
from (select trunc(sysdate) + 1 - level as today 
     from dual 
     connect by level <= 30) 
     , mytable 
where myfield in ('A', 'B') 
and somedate >= trunc(sysdate) - 30 
group by today, myfield 
order by today desc, myfield asc 
/

編輯

我已經運行原來的查詢,我的一個修訂對一些測試數據。你將不得不把我的話,這兩個resulsets實際上是相同的 - 或你自己:)

查詢返回試試吧:

TODAY  M AB_COUNT 
----------- - ---------- 
26-SEP-2009 A   0 
26-SEP-2009 B   0 
25-SEP-2009 A   2 
25-SEP-2009 B   2 
24-SEP-2009 A   2 
24-SEP-2009 B   0 
... 
29-AUG-2009 A   1 
29-AUG-2009 B   2 
28-AUG-2009 A   1 
28-AUG-2009 B   0 

60 rows selected. 

SQL> 

我的查詢返回:

TODAY  M AB_COUNT 
----------- - ---------- 
26-SEP-2009 A   0 
26-SEP-2009 B   0 
25-SEP-2009 A   2 
25-SEP-2009 B   2 
24-SEP-2009 A   2 
24-SEP-2009 B   0 
... 
29-AUG-2009 A   1 
29-AUG-2009 B   2 
28-AUG-2009 A   1 
28-AUG-2009 B   0 

60 rows selected. 

SQL>