| 類型 | 關鍵字 | 說明 |
|---|---|---|
| 交叉連接 | CROSS JOIN / JOIN / , | 笛卡爾積,兩表行數相乘,無條件時極慢 |
| 內連接 | INNER JOIN | 等值連接,僅回傳符合條件的匹配行 |
| 左外連接 | LEFT [OUTER] JOIN | 回傳左表所有行 + 右表匹配行,無匹配則 NULL |
| 右外連接 | RIGHT [OUTER] JOIN | 回傳右表所有行 + 左表匹配行,無匹配則 NULL |
-- user 表 id | name ---|----- 1 | libk 2 | zyfon 3 | daodao -- user_action 表 user_id | action --------|------- 1 | jump 1 | kick 1 | jump 2 | run 4 | swim
SELECT id, name, action FROM user AS u LEFT JOIN user_action AS a ON u.id = a.user_id;
id | name | action ---|-------|------- 1 | libk | jump ← 匹配 1 | libk | kick ← 匹配 1 | libk | jump ← 匹配(重複行) 2 | zyfon | run ← 匹配 3 | daodao| NULL ← 左表有、右表無 -- user_action 中 user_id=4 的 swim 不出現(右表無匹配左表)
運作邏輯:讀取左表一行 → 找出所有 ON 匹配的右表行 → 產生 N 行結果 → 繼續下一行左表。
SELECT id, name, action FROM user AS u LEFT JOIN user_action AS a ON u.id = a.user_id WHERE a.user_id IS NULL; -- 注意:用 IS NULL,且欄位必須 NOT NULL
id | name | action ---|-------|------- 3 | daodao| NULL
SELECT * FROM t1, t2 WHERE t1.id=t2.idSELECT * FROM t1 LEFT JOIN t2 ON t1.id=t2.id(多表鏈式)USING (col) 等同 ON t1.col=t2.colSELECT artists.Artist, cds.title, genres.genre FROM cds LEFT JOIN genres ON cds.genreID = genres.genreID LEFT JOIN artists ON cds.artistID = artists.artistID WHERE genres.genre = 'Pop';
USE INDEX (key_list):強制使用指定索引IGNORE INDEX (key_list):忽略指定索引STRAIGHT_JOIN:強制先讀右表(適合右表行數極少時)NATURAL JOIN:自動匹配同名欄位(慎用)舊版:SELECT ... FROM t1, t2 LEFT JOIN t3 ON ... WHERE ... 實際執行為 FROM t1, (t2 LEFT JOIN t3 ...)
新版需明確括號:SELECT ... FROM (t1, t2) LEFT JOIN t3 ON ...
| 類型 | SQL 範例 | 結果特徵 |
|---|---|---|
| 內連接 | SELECT A.Name, B.Hobby FROM A INNER JOIN B ON A.id=B.id | 僅雙方都有的記錄 |
| 左外連接 | SELECT A.Name, B.Hobby FROM A LEFT JOIN B ON A.id=B.id | 保留 A 所有行,B 無匹配則 NULL |
| 右外連接 | SELECT A.Name, B.Hobby FROM A RIGHT JOIN B ON A.id=B.id | 保留 B 所有行,A 無匹配則 NULL |
USING (c1,c2,c3) 等同 ON a.c1=b.c1 AND a.c2=b.c2 AND a.c3=b.c3NATURAL [LEFT] JOIN 相當於包含所有同名欄位的 USING 子句LEFT JOIN 減少全掃描