萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> MySQL 教學

MySQL LEFT JOIN、RIGHT JOIN、INNER JOIN 差異完整圖解與實戰

核心概念速覽

Join 類型結果集口訣
INNER JOIN雙方**都匹配**的行交集
LEFT JOIN左表**全部** + 右表匹配行(無則 NULL)左全右部
RIGHT JOIN右表**全部** + 左表匹配行(無則 NULL)右全左部

MySQL 特殊:不支援 RIGHT JOIN 語法糖

MySQL 解析器將 RIGHT JOIN 內部轉換為 LEFT JOIN(交換表順序)。**建議統一使用 LEFT JOIN**,可讀性更好、避免混淆。

-- 等價轉換
SELECT * FROM A RIGHT JOIN B ON A.id = B.id;
-- 等同於
SELECT * FROM B LEFT JOIN A ON B.id = A.id;

實戰範例:兩張表資料

-- 表 A
+------+-----------+
| aID  | aNum      |
+------+-----------+
| 1    | a20050111 |
| 2    | a20050112 |
| 3    | a20050113 |
| 4    | a20050114 |
| 5    | a20050115 |
+------+-----------+

-- 表 B
+------+------------+
| bID  | bName      |
+------+------------+
| 1    | 2006032401 |
| 2    | 2006032402 |
| 3    | 2006032403 |
| 4    | 2006032404 |
| 8    | 2006032408 |
+------+------------+

1. LEFT JOIN(以 A 為基準)

SELECT * FROM A LEFT JOIN B ON A.aID = B.bID;
+------+-----------+------+------------+
| aID  | aNum      | bID  | bName      |
+------+-----------+------+------------+
| 1    | a20050111 | 1    | 2006032401 |
| 2    | a20050112 | 2    | 2006032402 |
| 3    | a20050113 | 3    | 2006032403 |
| 4    | a20050114 | 4    | 2006032404 |
| 5    | a20050115 | NULL | NULL       |  -- A 有、B 無 → NULL
+------+-----------+------+------------+

2. RIGHT JOIN(以 B 為基準,MySQL 內部轉 LEFT JOIN)

SELECT * FROM A RIGHT JOIN B ON A.aID = B.bID;
+------+-----------+------+------------+
| aID  | aNum      | bID  | bName      |
+------+-----------+------+------------+
| 1    | a20050111 | 1    | 2006032401 |
| 2    | a20050112 | 2    | 2006032402 |
| 3    | a20050113 | 3    | 2006032403 |
| 4    | a20050114 | 4    | 2006032404 |
| NULL | NULL      | 8    | 2006032408 |  -- B 有、A 無 → NULL
+------+-----------+------+------------+

3. INNER JOIN(僅雙方匹配)

SELECT * FROM A INNER JOIN B ON A.aID = B.bID;
-- 等同舊寫法:SELECT * FROM A, B WHERE A.aID = B.bID;
+------+-----------+------+------------+
| aID  | aNum      | bID  | bName      |
+------+-----------+------+------------+
| 1    | a20050111 | 1    | 2006032401 |
| 2    | a20050112 | 2    | 2006032402 |
| 3    | a20050113 | 3    | 2006032403 |
| 4    | a20050114 | 4    | 2006032404 |
+------+-----------+------+------------+

進階:LEFT JOIN 多表鏈式關聯

SELECT p.price, pd.name, m.manufacturers_name
FROM products p
LEFT JOIN products_description pd ON p.products_id = pd.products_id
LEFT JOIN manufacturers m ON p.manufacturers_id = m.manufacturers_id;

執行順序: 先 p LEFT JOIN pd 產生中間結果,再 LEFT JOIN m。括號決定關聯順序。

關鍵陷阱:ON vs WHERE 條件位置

-- 錯誤:WHERE 過濾會將 LEFT JOIN 退化為 INNER JOIN
SELECT * FROM A LEFT JOIN B ON A.id = B.id WHERE B.name = 'test';

-- 正確:右表條件放在 ON 中,保留 LEFT JOIN 語義
SELECT * FROM A LEFT JOIN B ON A.id = B.id AND B.name = 'test';

原則: 右表的過濾條件寫在 ON,左表的過濾條件寫在 WHERE。

效能建議

  • 小表驅動大表:將小結果集放左側(LEFT JOIN)或右側(RIGHT JOIN)
  • 關聯欄位**必須加索引**
  • 避免 SELECT *,只查需要欄位
  • 大表關聯考慮 STRAIGHT_JOIN 強制順序或改寫為子查詢
copyright © 萬盛學電腦網 all rights reserved