2012-06-27 100 views
1

我有一個SELECT語句是這樣的:在SQL Server SELECT - 替代子查詢

SELECT 
T1.COD, 
T1.NAME, 
(SELECT MAX(T2.DATA) 
    FROM dbo.TAB2 T2 
    WHERE T2.COD = T1.COD) AS ENDDATA 
FROM dbo.TAB1 AS T1 WITH (NOLOCK) 

是否有使用SUBQUERY替代?有沒有可能使用JOIN?

我必須找到更有效的解決方案來運行此查詢。

非常感謝。

+0

子查詢沒有問題,因爲你不得不左鍵(通過代碼選擇max(data),來自dbo.tab2組的代碼)t2 on t1.code = t2.code' – SQLMason

回答

0

是的,你可以使用JOIN:

SELECT 
    T1.COD, 
    T1.NAME, 
    MAX(T2.DATA) AS ENDDATA 
FROM dbo.TAB1 AS T1 WITH (NOLOCK) 
JOIN dbo.TAB2 T2 WITH (NOLOCK) -- Assumed 
    ON T2.COD = T1.COD 
GROUP BY 
    T1.COD, 
    T1.NAME 
0
SELECT T1.COD, 
     T1.NAME, 
     MAX(T2.DATA) 
FROM  TAB1 AS T1 
JOIN  TAB2 AS T2 
ON  T2.COD = T1.COD 
GROUP BY T1.COD, 
     T1.NAME; 
1

要返回相同的結果作爲您的原始查詢,您需要:

SELECT T1.COD, T1.NAME, s.ENDDATA 
FROM dbo.TAB1 T1 WITH (NOLOCK) left outer join 
    (SELECT t2.cod, MAX(T2.DATA) as EndData 
     FROM dbo.TAB2 T2 
     group by T2.COD 
    ) s 
    on t1.cod = s.cod 

由從事羣體之外的加入更改查詢的語義。特別是,即使在T1中可能存在重複項,每個COD/NAME也只會返回一行。這可能是需要的。但是,您的原始查詢將具有重複項。

另外,你爲什麼要在TAB1上打開NOLOCK而不在TAB2上?

0

爲什麼你不想使用子選擇?您可以用outer申請聲明(從我的角度來看,這看起來更好)替代它,但在大多數情況下,您將獲得相同的執行計劃。是的,實際上它取決於你的索引(我假設你有TAB2表中的COD索引)和數據(我假設這兩個表中的行數都大或小,TAB2中的行數絕對大於TAB1中的行數)。

通過COD和NAME進行分組的解決方案是最糟糕的解決方案。子查詢解決方案與outer apply相同。使用outer apply的解決方案或多或少都是很好的解決方案(甚至可以更好地使用cross apply,但在這種情況下,應確保TAB1中沒有行,而TAB1中沒有關聯行)。