-- 1. ANSI ON 標準寫法 SELECT * FROM film JOIN film_actor ON (film.film_id = film_actor.film_id); -- 2. ANSI USING 簡潔寫法(同名欄位) SELECT * FROM film JOIN film_actor USING (film_id); -- 3. Theta 風格(舊式 WHERE 連接) SELECT * FROM film, film_actor WHERE film.film_id = film_actor.film_id;
| 維度 | ON | USING | WHERE (Theta) |
|---|---|---|---|
| 適用條件 | 任意關聯條件 | 關聯欄位同名 | 任意條件 |
| 條件分離 | 關聯條件在 ON,過濾條件在 WHERE | 同 ON | 關聯與過濾混在 WHERE |
| 欄位消重 | 雙邊欄位保留(film_id 出現兩次) | 關聯欄位合併(film_id 僅一次) | 雙邊保留 |
| 欄位引用 | 需加表前綴:film.film_id | 可直接用欄位名:film_id | 需加表前綴 |
| 可讀性 | 清晰、標準 | 簡潔、同名時首選 | 複雜查詢難維護 |
| 相容性 | 所有資料庫 | 大多數資料庫 | 所有資料庫 |
-- USING:film_id 僅出現一次 SELECT * FROM film JOIN film_actor USING (film_id) LIMIT 1\G *************************** 1. row *************************** film_id: 96 title: BREAKING HOME ... actor_id: 17 last_update: 2006-02-15 05:05:03 -- ON:film_id 出現兩次 SELECT * FROM film JOIN film_actor ON (film.film_id = film_actor.film_id) LIMIT 1\G *************************** 1. row *************************** film_id: 96 title: BREAKING HOME ... actor_id: 17 film_id: 96 -- 重複! last_update: 2006-02-15 05:05:03
-- USING:可直接引用,無歧義 SELECT film.title, film_id FROM film JOIN film_actor USING (film_id); -- ✅ OK -- ON:必須指定表名,否則報錯 SELECT film.title, film_id FROM film JOIN film_actor ON (film.film_id = film_actor.film_id); -- ERROR 1052 (23000): Column 'film_id' in field list is ambiguous
EXPLAIN EXTENDED SELECT * FROM film JOIN film_actor USING (film_id) WHERE actor_id = 17\G SHOW WARNINGS\G -- Message: select ... from `film` join `film_actor` where ( (`film`.`film_id` = `film_actor`.`film_id`) and ... )
MySQL 優化器會將所有寫法統一轉換為 Theta 風格執行,**效能完全相同**。
-- 推薦寫法:層次清晰 SELECT f.title, a.first_name, a.last_name, c.name AS category FROM film f JOIN film_actor fa ON f.film_id = fa.film_id JOIN actor a ON fa.actor_id = a.actor_id JOIN film_category fc ON f.film_id = fc.film_id JOIN category c ON fc.category_id = c.category_id WHERE f.length > 120 AND a.actor_id = 17;