Navicat 部落格

在 MySQL 中模擬外部聯結 2022 年 10 月 24 日,由 Robert Gravelle 撰寫

上週的文章詳細介紹了 SELECT 查詢中的外部聯結。它是一種 JOIN 類型,可以從相關資料表中傳回相符和不相符的列。可惜的是,並不是所有資料庫(DB)供應商都支援它,包括 MySQL。但這沒有關係,因為可以透過結合其他三種 JOIN 類型(即 LEFT、INNER 和 RIGHT 連接)來模擬外部聯結。在本文中,我們將詳細了解 LEFT 和 RIGHT 聯結,以及使用 INNER JOIN 結合它們時,如何變成 OUTER JOIN。

LEFT 聯結

LEFT JOIN 傳回左資料表中的所有列和右資料表中相符的列。如果在右資料表中找不到相符的列,則傳回 NULL。以下是它的語法:

SELECT
    select_list
FROM
    T1
LEFT JOIN T2 ON
    join_predicate;

下面的 VEN 圖說明了使用 LEFT JOIN 子句可以從兩個資料表 T1 和 T2 中擷取哪些資料:

left_join_diagram (31K)

RIGHT 聯結

RIGHT JOIN 傳回右資料表中的所有列和左資料表中相符的列。如果在左資料表中找不到相符的列,則傳回 NULL。以下是它的語法:

SELECT 
    select_list
FROM 
    T1
RIGHT JOIN T2 ON join_predicate;

下面的 VEN 圖說明了使用 RIGHT JOIN 子句可以從兩個資料表 T1 和 T2 中擷取哪些資料:

right_join_diagram (18K)

結合聯結以模擬 OUTER JOIN

整個整個資料庫社群都知道 MySQL 不支援 FULL OUTER JOIN。這個缺陷的一個常見解決辦法是使用 UNION ALL 結合來自兩個資料表的 LEFT JOIN、INNER JOIN 和 RIGHT JOIN 的三個結果集,並將 join_column IS NULL 條件加到 LEFT 和 RIGHT 聯結。

為了示範如何模擬以上的外部聯結,我們將使用與上週「了解 SQL 外部聯結」文章中相同的專案管理資料庫編寫查詢,但這次是在 MySQL 中。

在左資料表中尋找不相符的記錄

第一個查詢將傳回僅在左資料表中找到的列。以下的查詢搭配使用 LEFT 聯結與 WHERE 子句來實現此效果,該子句指定右資料表中的共同(聯結)欄為 NULL:

pm_Left_join_query (37K)

在第二個資料表中尋找不相符的記錄

第二個查詢將傳回僅在右資料表中找到的列。為此,我們將搭配使用 RIGHT 聯結與 WHERE 子句,該子句指定左資料表中的共同(聯結)欄為 NULL:

pm_Right_join_query (40K)

在兩個資料表中尋找相符的記錄

若要尋找出現在兩個資料表中的記錄,我們可以使用標準(INNER)JOIN,如下所示:

pm_Inner_join_query (45K)

當使用 UNION ALL 結合這三個獨立的查詢時,會產生與 OUTER JOIN 相同的結果:

pm_query (140K)

總結

在本文中,我們學習了更多有關 LEFT 和 RIGHT 聯結的知識,以及當使用 INNER JOIN 結合它們時,如何變成 OUTER JOIN。和上週一樣,有一件要注意的事情。當與 ORDER BY 和/或 LIMIT 查詢一起使用時,這種方法在查詢大型資料表時可能效率非常低,因為它使用檔案排序(filesort)。在這種情況下,你可能需要採用另一種方法。

Navicat 文章
頻道記錄
分享
部落格封存檔