首先,是完全等效的,第一個查詢應該已被寫入
SELECT mw.*,
nvs.*
FROM mst_words mw
LEFT JOIN (SELECT *
FROM vocab_stats
WHERE owner = 1111) AS nvs ON mw.no = nvs.vocab_no
WHERE (nvs.correct > 0)
AND mw.level = 1
這樣兆瓦*和NVS *一起產生相同的一組作爲第二個查詢的單數*。你寫的查詢可以使用INNER JOIN,因爲它在nvs.correct上包含一個過濾器。
一般形式
TABLEA LEFT JOIN TABLEB ON <CONDITION>
attempts
找到基於條件表B的記錄。如果失敗,則保留TABLEA的結果,並將TableB中的所有列設置爲NULL。相比之下
TABLEA INNER JOIN TABLEB ON <CONDITION>
也attempts
找到基於條件表B的記錄。 但是,如果失敗,TableA中的特定記錄將從輸出結果集中刪除。
CROSS JOIN的ANSI標準在兩個表之間產生一個Cartesian product。
TABLEA CROSS JOIN TABLEB
-- # or in older syntax, simply using commas
TABLEA, TABLEB
語法的意圖是TABLEA中的EACH行被連接到TABLEB中的EACH行。因此A中的4行和B中的3行產生了12行輸出。當與WHERE子句中的條件配對時,它有時產生與INNER JOIN相同的行爲,因爲它們表達相同的事物(A和B之間的條件=>保留或不)。但是,在閱讀使用INNER JOIN而不是逗號的意圖時,它會更清晰。
從性能上看,大多數DBMS將比INNER JOIN更快地處理LEFT連接。逗號表示法可能會導致數據庫系統錯誤地解釋意圖併產生錯誤的查詢計劃 - 這是SQL92表示法的另一個優點。
爲什麼我們需要LEFT JOIN?如果上面的LEFT JOIN的解釋仍然不夠(保留A中的記錄而B中沒有匹配),則認爲要達到相同的效果,您需要在兩組之間使用舊的逗號符號實現相同的複雜UNION影響。 但如前所述,這不適用於您的示例,這實際上是隱藏在LEFT JOIN後面的INNER JOIN。
注:
- 的RIGHT JOIN相同LEFT,不同之處在於它與TABLEB(右側)開始代替A.
- 右和左JOINS都是外部聯接。字OUTER是可選的,即它可以被寫爲
LEFT OUTER JOIN
。
- 第三種OUTER連接是FULL OUTER連接,但這裏不討論。
第一個是OUTER(本例中爲LEFT)JOIN示例(ANSI-92),後者是INNER JOIN(ANSI-89,不支持OUTER連接)。除非總是有記錄來鏈接這兩個表格,否則他們不可能返回相同的結果。 –
@OMG後者不是'INNER JOIN。由於它是笛卡兒乘積,因此它更接近CROSS JOIN定義。 – RichardTheKiwi
ANSI-89語法...解釋計劃與使用'... FROM VOCAB_STATS s JOIN MSTWORDS w ON w.no = v.vocab_no ...'相同。再次 - **否,第二個查詢不返回笛卡爾積**。 –