... FROM table1 INNER|LEFT|RIGHT JOIN table2 ON condition
table1:左表(驅動表)table2:右表(被驅動表)| 類型 | 別名 | 語義 | 結果集 |
|---|---|---|---|
| INNER JOIN | 內連接/等值連接 | 雙方匹配的記錄 | 交集 |
| LEFT JOIN | 左外連接 | 左表全量 + 右表匹配(無則 NULL) | 左集合為主 |
| RIGHT JOIN | 右外連接 | 右表全量 + 左表匹配(無則 NULL) | 右集合為主 |
⚠️ MySQL **不支援 FULL JOIN**,可用 LEFT JOIN UNION RIGHT JOIN 模擬。
A 表: (1,Pirate) (2,Monkey) (3,Ninja) (4,Spaghetti)
B 表: (1,Rutabaga) (2,Pirate) (3,Darth Vader) (4,Ninja)
SELECT * FROM A INNER JOIN B ON A.name = B.name;
-- 結果: (1,Pirate,2,Pirate) (3,Ninja,4,Ninja)

SELECT * FROM A LEFT JOIN B ON A.name = B.name;
-- 結果: A 全量,B 匹配行或 NULL

衍生用法:
WHERE B.id IS NULLWHERE A.id IS NOT NULL AND B.id IS NOT NULL鏡像 LEFT JOIN,結果以 B 表全量為主。
笛卡爾積(16 行 = 4×4)。MySQL 中 CROSS JOIN = INNER JOIN(無 ON 條件時)。
SELECT * FROM A CROSS JOIN B;
-- 等價於: SELECT * FROM A JOIN B; (無 ON)
SELECT * FROM A LEFT JOIN B ON A.name = B.name
UNION
SELECT * FROM A RIGHT JOIN B ON A.name = B.name;

-- 顯式 (推薦,可讀性強)
SELECT * FROM a INNER JOIN b ON a.id = b.id;
-- 隱式 (舊語法,MySQL 優化器同等對待)
SELECT a.*, b.* FROM a, b WHERE a.id = b.id;
實測 10 萬數據性能幾乎相同,推薦顯式語法。
外連接產生 NULL 需額外過濾,增加開銷。
優化原則:盡可能將條件下推到 ON 子句,減少 WHERE 過濾量。
-- PASS: WHERE 過濾
SELECT * FROM A
INNER JOIN B ON B.name = A.name
LEFT JOIN C ON C.name = B.name
LEFT JOIN D ON D.id = C.id
WHERE C.status > 1 AND D.status = 1;
-- GREAT: ON 下推
SELECT * FROM A
INNER JOIN B ON B.name = A.name
LEFT JOIN C ON C.name = B.name AND C.status > 1
LEFT JOIN D ON D.id = C.id AND D.status = 1;
-- ON 過濾:左表全量,右表僅 status>1 的行參與匹配
SELECT * FROM product LEFT JOIN product_details
ON product.id = product_details.id AND product_details.id = 2;
-- WHERE 過濾:先全量 LEFT JOIN,再過濾
SELECT * FROM product LEFT JOIN product_details
ON product.id = product_details.id
WHERE product_details.id = 2;
前者保留左表所有行(右表無匹配則 NULL),後者相當於 INNER JOIN。
-- PASS: 子查詢 NOT EXISTS
INSERT INTO t1(a1)
SELECT b1 FROM t2
WHERE NOT EXISTS (SELECT 1 FROM t1 WHERE t1.id = t2.r_id);
-- GREAT: LEFT JOIN + IS NULL
INSERT INTO t1(a1)
SELECT b1 FROM t2
LEFT JOIN (SELECT DISTINCT id FROM t1) t1 ON t1.id = t2.r_id
WHERE t1.id IS NULL;
JOIN 可利用索引、避免相關子查詢逐行執行、優化器更易生成高效計劃。
EXPLAIN 分析執行計劃