首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 多表連接查詢通俗解析:INNER/LEFT/RIGHT JOIN 圖解與實戰

     編輯:MySQL 資料庫相關知識

核心概念:集合論視角

  • INNER JOIN = 交集 (A ∩ B) — 僅返回雙邊匹配行。
  • LEFT JOIN = 左集合全量 + 右匹配 (A ∪ (A ∩ B)) — 保左表所有行,右無匹配填 NULL。
  • RIGHT JOIN = 右集合全量 + 左匹配 — 保右表所有行,左無匹配填 NULL。

最小數據集演示

表 A

aidadate
1a1
2a2
3a3

表 B

bidbdate
1b1
2b2
4b4

三種 JOIN 結果對比

1. INNER JOIN

SELECT * FROM a INNER JOIN b ON a.aid = b.bid;
aidadatebidbdate
1a11b1
2a22b2

僅返回 aid=bid=1,2 的匹配行。

2. LEFT JOIN

SELECT * FROM a LEFT JOIN b ON a.aid = b.bid;
aidadatebidbdate
1a11b1
2a22b2
3a3NULLNULL

左表 aid=3 無匹配,右側填 NULL。

3. RIGHT JOIN

SELECT * FROM a RIGHT JOIN b ON a.aid = b.bid;
aidadatebidbdate
1a11b1
2a22b2
NULLNULL4b4

右表 bid=4 無匹配,左側填 NULL。

實戰場景:用戶與訂單

表結構

Persons (Id_P, LastName, FirstName, Address, City)
Orders  (Id_O, OrderNo, Id_P)

需求:列出所有人及其訂單 (無訂單也顯示)

SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
FROM Persons
LEFT JOIN Orders ON Persons.Id_P = Orders.Id_P
ORDER BY Persons.LastName;

結果

LastNameFirstNameOrderNo
AdamsJohn22456
AdamsJohn24562
CarterThomas77895
CarterThomas44678
BushGeorgeNULL

Bush George 無訂單,OrderNo 顯示 NULL,完美符合「保左表」語義。

進階:多表鏈式 JOIN

SELECT u.name, o.order_no, p.product_name
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
LEFT JOIN order_items oi ON o.id = oi.order_id
LEFT JOIN products p ON oi.product_id = p.id
WHERE u.status = 1;
  • 每個 LEFT JOIN 獨立保左表 (上一步結果集)。
  • WHERE 條件放在最後,**右表列不得出現在 WHERE** (除非 IS NULL 判斷),否則退化為 INNER JOIN。

性能優化鐵律

  1. 小表驅動大表:左表盡量小 (過濾後),右表有索引。
  2. JOIN 列類型一致:INT 關聯 INT,VARCHAR 關聯 VARCHAR,長度一致,否則隱式轉換導致索引失效。
  3. 優先 INNER JOIN:語義允許時用 INNER JOIN,優化器選擇更多 (可交換表順序)。
  4. 避免 SELECT *:僅查詢所需列,減少網絡/內存/臨時表開銷。
  5. EXPLAIN 關鍵列:type=ref/eq_ref (索引查找),Extra=Using where; Using index (覆蓋索引)。

總結

JOIN 本質是集合運算。牢記「LEFT 保左、RIGHT 保右、INNER 取交」,結合「右表條件寫 ON、WHERE 只過左表」原則,即可寫出正確、高效的多表查詢。實戰中 90% 場景用 INNER + LEFT 組合即可覆蓋,RIGHT JOIN 可通過交換表順序轉為 LEFT JOIN,統一代碼風格。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved