2016-06-28 112 views
2

我在一個查詢中有多個JOIN語句,我必須檢查JOIN中的兩個設置。如何以最好的方式做到這一點?JOIN中的SQL查詢優化問題

table: WebSettings 
------------------------------------------------------- 
Name   | Setting | InstID | WebSettingID 
------------------------------------------------------- 
'EnableError' | 2 | 1111 | 1 
'ErrorsSetting' | 0 | 2121 | 2 

Index : 

InstID 
WebSettingID (InstID) 


table: InstProd 
------------------------------------------------------- 
InstitutionID | Name 
------------------------------------------------------- 
1111  | 'Bank of Ind' 
2121  | 'IOB' 


Index : 

InstitutionID 


SELECT 

Column1, 
DATEADD(.....) 

FROM 
dbo.InstProd I 
INNER JOIN dbo.WebSettings WS1 ON 
WS1.InstitutionID = I.InstID AND 
WS1.Name = 'EnableError' AND WS1.Setting=2 
INNER JOIN dbo.WebSettings WS2 ON 
WS2.InstitutionID = I.InstID AND 
WS2.Name = 'ErrorsSetting' AND WS2.Setting=0 
WHERE..... 

我要檢查在JOIN

一個WebSettings = 2other = 0是否有這樣做的一個最好的解決辦法?

+1

請解釋一下你更好的要求。你想要輸出什麼? –

+0

添加表格定義和索引! – jarlh

+0

該代碼甚至不會運行。您在代碼中缺少AND/OR子句。 –

回答

1

是的,你不需要加入WebSettings兩次,雖然你沒有發表您預期的輸出,所以我不知道到底該怎麼做,而是調整這個:

SELECT <column1>,<column2>, 
     MAX(CASE WHEN ws.Name = 'EnableError' AND ws.settings = 2 THEN <YourDesiredColumn> END) as enable_column, 
     MAX(CASE WHEN ws.Name = 'ErrorsSetting' AND ws.settings = 0 THEN <YourDesiredColumn2> END) as Errors_column 
FROM bo.InstProd I 
INNER JOIN dbo.WebSettings WS1 ON 
WS1.InstitutionID = I.InstID AND 
(WS.Name,ws.setting) in (('EnableError',2),('ErrorsSetting',0)) 
GROUP BY <column1>,<column2> 

這將就像查詢一樣,在同一行中爲您提供啓用和錯誤列。

+0

驗證後我會回來。謝謝 – Keppy

+0

我已經試過這個,沒有看到任何性能改善相比,我的腳本,並決定與我的。感謝您的支持。 – Keppy

1

最小化JOINS可能會導致你期待什麼,如果你不使用WS2

SELECT 
Column1, 
DATEADD(.....) 

FROM 
dbo.InstProd I 
INNER JOIN dbo.WebSettings WS1 ON WS1.InstitutionID = I.InstID 
           AND (WS1.Name = 'EnableError' 
            AND WS1.Setting = 2) 
           OR (WS1.Name = 'ErrorsSetting' 
            AND WS1.Setting = 0) 
WHERE..... 
+0

驗證後我會回來。謝謝 – Keppy

+1

我已經試過了,沒有看到任何與我的腳本相比的性能改善,並決定和我一起去。感謝您的支持。 – Keppy

0

您可以決定不使用JOIN,因爲我下面的方法解決

如果希望所有InstProdEnableError = 2ErrorSettings = 0

試試這個:

SELECT I.* 
FROM InstProd I 
WHERE EXISTS 
    (SELECT 'EnableError = 2' 
     FROM WebSettings WS 
     WHERE WS.InstID = I.InstitutionID 
     AND WS.Name = 'EnableError' AND WS.Setting = 2) 
AND EXISTS 
    (SELECT 'EnableError = 2' 
     FROM WebSettings WS 
     WHERE WS.InstID = I.InstitutionID 
     AND WS.Name = 'ErrorSettings' AND WS.Setting = 0) 

如果希望所有InstProd與檢查約兩設定值

試試這個:

SELECT I.*, 
CASE 
    WHEN 
     (SELECT COUNT(1) 
     FROM WebSettings WS 
     WHERE WS.InstID = I.InstitutionID 
     AND WS.Name = 'EnableError' AND WS.Setting = 2) > 0 
     AND 
     (SELECT COUNT(1) 
     FROM WebSettings WS 
     WHERE WS.InstID = I.InstitutionID 
     AND WS.Name = 'ErrorSettings' AND WS.Setting = 0) > 0 
    THEN 'OK' 
    ELSE 'KO' 
END 
FROM InstProd I 
+0

謝謝。從性能的角度來看,你會建議哪一個?如果我的記錄數很高,加入還是存在? – Keppy

+0

我認爲不存在所有情況下的命令。取決於你想要的,在這種情況下,存在子句可以用於第一種情況(因爲你不顯示這些信息,但你只用於條件),對於第二種情況我更喜歡(因爲只有兩個字段)select中的子查詢字段列表。使用JOIN時,您必須應用組或獨特的子句來丟棄重複的行 –