JOIN 是多表關聯查詢的核心。本文以兩張簡單表為例,通過數據演示直觀解析 INNER JOIN、LEFT JOIN、RIGHT JOIN 的結果差異,並給出 Venn 圖思維模型與實戰場景。
-- 表 a
aid | adate
1 | a1
2 | a2
3 | a3
-- 表 b
bid | bdate
1 | b1
2 | b2
4 | b4
| JOIN 類型 | SQL | 結果集 | 通俗理解 |
|---|---|---|---|
| INNER JOIN | SELECT * FROM a INNER JOIN b ON a.aid = b.bid |
1 a1 b1 2 a2 b2 | 僅返回雙方都匹配的行 (交集) |
| LEFT JOIN | SELECT * FROM a LEFT JOIN b ON a.aid = b.bid |
1 a1 b1 2 a2 b2 3 a3 NULL | 返回左表所有行,右表無匹配則填 NULL |
| RIGHT JOIN | SELECT * FROM a RIGHT JOIN b ON a.aid = b.bid |
1 a1 b1 2 a2 b2 NULL NULL b4 | 返回右表所有行,左表無匹配則填 NULL |
INNER JOIN = A ∩ B
LEFT JOIN = A ∪ (A ∩ B) → 所有 A
RIGHT JOIN = B ∪ (A ∩ B) → 所有 B
-- Persons 表
Id_P | LastName | FirstName | Address | City
1 | Adams | John | Oxford St | London
2 | Bush | George | Fifth Ave | New York
3 | Carter | Thomas | Changan St | Beijing
-- Orders 表
Id_O | OrderNo | Id_P
1 | 77895 | 3
2 | 44678 | 3
3 | 22456 | 1
4 | 24562 | 1
5 | 34764 | 65 -- 孤兒訂單
-- 需求:列出所有人及其訂單 (無訂單也顯示)
SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
FROM Persons
LEFT JOIN Orders ON Persons.Id_P = Orders.Id_P
ORDER BY Persons.LastName;
結果:
Adams John 22456
Adams John 24562
Bush George NULL
Carter Thomas 77895
Carter Thomas 44678
關鍵點:
LEFT JOIN保證左表 (Persons) 所有行出現,右表無匹配顯示 NULL。若改為INNER JOIN,Bush 將消失。
a LEFT JOIN b ON ... LEFT JOIN c ON ...,以第一張表為基準。LEFT JOIN b ON a.id=b.id AND b.status=1 (ON 中過濾) vs WHERE b.status=1 (WHERE 中過濾會將 LEFT JOIN 退化為 INNER JOIN)。JOIN b USING (id)。