TL;DR | 面試情境模擬 #
👴 面試官:SQL 的 JOIN 類型有哪些?差別在哪?
🧑💻 你:最常用的有四種。INNER JOIN 只回傳兩張表都有匹配的資料(交集);LEFT JOIN 保留左表所有資料,右表沒有對應的填 NULL;RIGHT JOIN 反過來;FULL OUTER JOIN 兩張表都全部保留,沒有對應的都填 NULL。實務上 INNER 和 LEFT 最常用。
範例資料 #
users 表 orders 表
+----+--------+ +----+---------+---------+
| id | name | | id | user_id | amount |
+----+--------+ +----+---------+---------+
| 1 | Alice | | 1 | 1 | 100 |
| 2 | Bob | | 2 | 1 | 200 |
| 3 | Carol | | 3 | 4 | 300 |
+----+--------+ +----+---------+---------+
(user_id=4 在 users 表不存在)
(Bob 和 Carol 沒有訂單)
四種 JOIN 圖解 #
INNER JOIN — 只取交集 #
users ──○ INNER JOIN ○── orders
↓
只回傳 user_id 在兩張表都存在的資料
SELECT u.name, o.amount
FROM users u
INNER JOIN orders o ON u.id = o.user_id
結果:
Alice | 100
Alice | 200
-- Bob、Carol 沒有訂單,不出現
-- user_id=4 的訂單,users 裡沒有,也不出現
LEFT JOIN — 左表全保留 #
SELECT u.name, o.amount
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
結果:
Alice | 100
Alice | 200
Bob | NULL ← Bob 沒訂單,填 NULL
Carol | NULL ← Carol 沒訂單,填 NULL
場景:查詢所有使用者和他們的訂單,沒有訂單的也要顯示。
RIGHT JOIN — 右表全保留 #
SELECT u.name, o.amount
FROM users u
RIGHT JOIN orders o ON u.id = o.user_id
結果:
Alice | 100
Alice | 200
NULL | 300 ← user_id=4 不存在於 users,填 NULL
實務上 RIGHT JOIN 較少用,通常直接改寫成 LEFT JOIN(交換表的順序)。
FULL OUTER JOIN — 兩邊全保留 #
SELECT u.name, o.amount
FROM users u
FULL OUTER JOIN orders o ON u.id = o.user_id
結果:
Alice | 100
Alice | 200
Bob | NULL
Carol | NULL
NULL | 300
核心差異 #
| JOIN 類型 | 保留 | NULL 填充 |
|---|---|---|
| INNER JOIN | 兩表都有的資料 | 不填 NULL |
| LEFT JOIN | 左表全部 | 右表無對應 → NULL |
| RIGHT JOIN | 右表全部 | 左表無對應 → NULL |
| FULL OUTER JOIN | 兩表全部 | 無對應的雙方都填 NULL |
💡 面試官可能會追問 #
Q1:CROSS JOIN 是什麼? #
笛卡爾積(Cartesian Product),不需要 ON 條件,直接把兩張表的每一筆資料兩兩配對。3 筆 × 3 筆 = 9 筆結果。實務上很少用,通常是誤寫 JOIN 忘記加 ON 造成的意外。
Q2:INNER JOIN 和 WHERE 子查詢哪個效能好? #
現代查詢優化器通常能產生相同的執行計劃,效能差異極小。但 JOIN 的語意更清晰、更符合 SQL 慣例,可讀性較好,通常優先使用 JOIN。
Q3:LEFT JOIN 後用 WHERE 過濾 NULL,效果等同 INNER JOIN? #
是的。LEFT JOIN ... WHERE right_table.id IS NOT NULL 等同於 INNER JOIN。但這樣寫會讓意圖不清晰,通常直接用 INNER JOIN。