我繼承了一個我不熟悉的語法的 SQL 查詢。
它看起來像
SELECT *
FROM #TableA AS TableA
INNER JOIN #TableB AS TableB
INNER JOIN #TableC AS TableC
ON TableC.Id1 = TableB.Id1
ON TableB.Id2 = TableA.Id2
它可以作業(SQL Server 2019)。
還有其他幾個不相關的查詢使用相同的語法,所以這絕對是故意的。
我首先認為ON子句的順序可能無關緊要,因為WHERE無論如何它們都可以移動到子句中。
但后來我嘗試了
SELECT *
FROM #TableA AS TableA
INNER JOIN #TableB AS TableB
INNER JOIN #TableC AS TableC
ON TableC.Id1 = TableB.Id1
AND TableC.Id3 = TableA.Id3
ON TableB.Id2 = TableA.Id2
并得到了帶有工具提示的曲線
'TableA.Id3' 無法系結
執行它會導致錯誤
'Id3' 附近的語法不正確
那么有人可以解釋這種語法是如何作業的嗎?
這是設定代碼
CREATE TABLE #TableA (Id1 int, Id2 int, Id3 int);
CREATE TABLE #TableB (Id1 int, Id2 int, Id3 int);
CREATE TABLE #TableC (Id1 int, Id2 int, Id3 int);
uj5u.com熱心網友回復:
當這些都是INNER JOINs 時,如果我說實話,這種語法有點毫無意義,但我稍后會介紹這一點。
讓我們以您的第一個陳述為例:
SELECT *
FROM #TableA AS TableA
INNER JOIN #TableB AS TableB
INNER JOIN #TableC AS TableC
ON TableC.Id1 = TableB.Id1
ON TableB.Id2 = TableA.Id2
我們這里有一個to的延遲ON子句。第二個子句實際上是針對on 的。INNER JOIN#TableBONINNER JOIN#TableB
使用此語法時,無法參考被延遲的表范圍之外的物件。這不是相同的語法(因為它使用派生表),但它可能更容易說明為什么你的第二個查詢失敗,這樣的查詢:JOIN
SELECT *
FROM #TableA AS TableA
CROSS JOIN (SELECT *
FROM #TableB AS TableB
INNER JOIN #TableC AS TableC ON TableC.Id1 = TableB.Id1
WHERE TableB.Id2 = TableA.Id2) BC;
這將產生類似的錯誤,因為別名為 as 的表TableA無法在派生表中參考。
在我看來,當你LEFT JOIN參與其中時,這種語法更有意義。取而代之的是:
SELECT *
FROM #TableA TableA
LEFT JOIN #TableB TableB
INNER JOIN #TableC TableC ON TableC.Id1 = TableB.Id1
ON TableB.Id2 = TableA.Id2;
所以在這里,LEFT JOIN要找到相關行,那么 to 中必須有相關行,如果沒有找到來自 的行,那么也不會加入到。這與以下查詢不同:TableCTableBINNER JOINTableB
SELECT *
FROM #TableA TableA
LEFT JOIN #TableB TableB ON TableB.Id2 = TableA.Id2
INNER JOIN #TableC TableC ON TableC.Id1 = TableB.Id1;
在這里,由于需要在 中找到一行,這將有效地將LEFT JOINtoTableB轉換為隱式,并且可以找到行的唯一方法是它具有非值(如果沒有找到行,這是不可能的)。INNER JOINTableCTableB.Id2NULL
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/522398.html
標籤:sqlsql服务器加入
上一篇:TO_CHAR(a_date,'Day')未按預期查詢
下一篇:odoo登錄微軟365失敗
