2012-12-14 251 views
0

我有這樣的說法:SQL語句 - 優化

SELECT * 
    FROM sgtn 
WHERE sgtn_kun_id IN (SELECT DISTINCT kun_id 
         FROM sgtn, kun 
         WHERE kun.kun_e_mail IN (LONG LIST OF EMAILS) 
           AND sgtn_kun_id = kun_id) 

     AND sgtn_strasse IN (SELECT sgtn.sgtn_strasse 
           FROM sgtn 
          WHERE sgtn_kun_id IN (SELECT DISTINCT kun_id 
                FROM sgtn, kun 
                WHERE kun.kun_e_mail IN (LONG LIST OF EMAILS) 
                  AND sgtn_kun_id = kun_id) 

          GROUP BY sgtn.sgtn_strasse 
          HAVING COUNT(sgtn_strasse) > 2); 

LONG LIST OF EMAILS是即: '[email protected]', '[email protected]', 。 。 。 '[email protected]'

正如你所看到的,我在這個查詢中重複了一部分subquerys。

我想知道是否以及如何取代LONG LIST OF EMAILS。它發生在我的陳述中兩次。是否有可能編輯此查詢,以便提到的LONG LIST OF EMAILS發生一次?

+1

進行檢測更換你的子查詢的和IN與連接,就可以實現在這種情況下,相同的結果,並且是* *很多更有效。一旦你知道他們是如何工作的,也會更容易。 – dtech

+1

另外:爲什麼這些電子郵件直接在您的查詢?它們不存儲在同一個數據庫中嗎?如果你的查詢應該檢索它們,不包含它們字面 – dtech

+1

你能解釋什麼試圖返回使用上面的查詢? –

回答

1

首先,你並不需要使用

IN (SELECT DISTINCT kun_id 
    FROM sgtn, kun 
    WHERE kun.kun_e_mail IN (LONG LIST OF EMAILS) 
    AND sgtn_kun_id = kun_id) 

它足夠

IN (SELECT kun_id 
    FROM kun 
    WHERE kun.kun_e_mail IN (LONG LIST OF EMAILS)) 

在你的列表中的多個sgtn_strasse和電子郵件中的行可以用

select * from (
    SELECT s.*, count(*) over (partition by sgtn_strasse) cnt_strasse 
    FROM sgtn s 
    WHERE sgtn_kun_id IN (SELECT kun_id 
         FROM kun 
         WHERE kun.kun_e_mail IN (LONG LIST OF EMAILS)) 
) 
WHERE cnt_strasse > 1; 
2

使用WITH子句:

WITH kun_list AS (
    SELECT DISTINCT kun_id 
     FROM sgtn, kun 
    WHERE kun.kun_e_mail IN (LONG LIST OF EMAILS) 
      AND sgtn_kun_id = kun_id) 

SELECT * 
    FROM sgtn 
WHERE sgtn_kun_id IN (SELECT kun_id 
         FROM kun_list) 

     AND sgtn_strasse IN (SELECT sgtn.sgtn_strasse 
           FROM sgtn 
          WHERE sgtn_kun_id IN (SELECT kun_id 
                FROM kun_list) 

          GROUP BY sgtn.sgtn_strasse 
          HAVING COUNT(sgtn_strasse) > 2); 
+0

這嚴格響應(正確)電子郵件清單重複,但沒有提供性能改進,因爲它基本上與查詢相同在OP。 –

1

你可以試試這個:

with CTE as (
SELECT sgtn.*, count(sgtn_strasse) OVER (PARTITION BY sgtn_strasse) cnt 
FROM sgtn 
WHERE sgtn_kun_id IN (SELECT kun_id FROM kun 
         WHERE kun.kun_e_mail IN (LONG LIST OF EMAILS)) 
) 

SELECT * FROM CTE WHERE CNT > 2 
+0

需要糾正兩件事:'sgtn_kun_id IN(SELECT *'part and in cte is no column'kun_id'。 –

+0

現在沒關係,本質上和我的答案一樣:) –