2013-08-21 28 views
0

我已經繼承了絕望需要重構的SQL查詢。查詢(6頁長)看起來是這樣的:使用不同的WHERE子句重構類似的子查詢

SELECT (count(*) from tab1, tab2, tab3 where tab1.value1 is not null 
and tab2.tab3id = tab3.id and tab3.value4 in (1,2,3) and tab3.value3 = 15 and tab2.value2 = 10 [...]) as RESULT1, 
SELECT (sum(tab3.value5) from [EXACT SAME QUERY AS ABOVE]) AS RESULT1_SUM 
SELECT (count(*) from tab1, tab2, tab3 where tab1.value1 is not null 
and tab2.tab3id = tab3.id and tab3.value4 in (1,2,3) and tab3.value3 = 15 and tab2.value2 = 27 [...]) as RESULT2, 
...[AD NAUSEAM for several more columns] 
UNION 
SELECT [same as first query, but now tab1.value1 is NULL] 
...[now sum()] 
FROM DUAL [of course!] 

這種混亂的最終結果是一個2行/ 16列結果,其中行由tab1.value1是否處於零不同(主要是複製和粘貼)子查詢,並且列的不同之處在於子查詢的WHERE子句的其他值中的小的任意變化。

   RESULT1 RESULT1_SUM RESULT2 RESULT2_SUM ... 
IS_NOT_NULL  300  120000  90   80000 
IS_NULL   70  90000  54   95000 

我必須複製這個相同的輸出。我的第一本能是將子查詢的常見元素放入WITH子句中。但我堅持如何獲得複製的「WHERE子句 - >不同的命名列」元素的微小變化,而不必爲每列使用單獨的子查詢。

我應該把它吸收並將子查詢轉儲到全局臨時表中還是有更好的方法?

+0

CAn讓它使用Case語句而不是子查詢? – HLGEM

+0

好吧,我發現我可以在FROM子句中有多個子查詢,但不加入它們,允許我在那裏設置列名,並且仍然能夠將子查詢的公共部分分解爲WITH子句。 它仍然有點冗餘,但看起來更好,至少。 – user1541898

+0

@HLGEM,也許對於總和部分,但它會看起來凌亂。我從來沒有在COUNT()聚合中看到CASE語句......這是否有效? – user1541898

回答

1

如果列之間的主要區別是tab2.value2,那麼你可以寫由兩個階段的查詢:通過tab2.value2

    1. 內查詢選擇相關的數據和分組它查詢分配結果到列

    因此,對於您的查詢的前半部分,它可能會升ook是這樣的:

    select 
        sum(case when val = 10 then cnt end) as RESULT1, 
        sum(case when val = 10 then sm end) as RESULT1_SUM, 
        sum(case when val = 15 then cnt end) as RESULT2, 
        sum(case when val = 15 then sm end) as RESULT2_SUM, 
        ... 
    from (
        select tab2.value2 as val, count(*) as cnt, sum(tab3.value5) as sm 
        from tab1, tab2, tab3 
        where tab1.value1 is not null 
        and tab2.tab3id = tab3.id 
        and tab3.value4 in (1,2,3) 
        and tab3.value3 = 15 
        group by tab2.value2 
    ) 
    
  • +0

    我不知道「案件」的事情會與COUNT()一起工作!優秀。起初我對內部查詢部分感到困惑,但現在它是有道理的。 – user1541898

    +0

    有一件事,RESULT1現在不應該是cnts的總和(),而RESULT1_SUM是短信的總和? – user1541898

    +0

    是的,你是對的。我修復了它。 – Codo