FROM 子句列出多張表,MySQL 依序產生笛卡兒積(Cross Join),再由 WHERE 過濾有效組合。
CREATE TABLE first (id TINYINT, first_name CHAR(10));
INSERT INTO first VALUES (1,'Tom'),(2,'Marry'),(3,'Jarry');
CREATE TABLE last (id TINYINT, last_name CHAR(10));
INSERT INTO last VALUES (2,'Stone'),(3,'White'),(4,'Donald');
mysql> SELECT * FROM first, last;
+------+------------+------+-----------+
| id | first_name | id | last_name |
+------+------------+------+-----------+
| 1 | Tom | 2 | Stone |
| 2 | Marry | 2 | Stone |
| 3 | Jarry | 2 | Stone |
| 1 | Tom | 3 | White |
| 2 | Marry | 3 | White |
| 3 | Jarry | 3 | White |
| 1 | Tom | 4 | Donald |
| 2 | Marry | 4 | Donald |
| 3 | Jarry | 4 | Donald |
+------+------------+------+-----------+
9 rows in set (3×3=9)
FROM 表序,不受 SELECT 列順影響。mysql> SELECT * FROM first, last WHERE first.id = last.id;
+------+------------+------+-----------+
| id | first_name | id | last_name |
+------+------------+------+-----------+
| 2 | Marry | 2 | Stone |
| 3 | Jarry | 3 | White |
+------+------------+------+-----------+
等價於標準 SQL INNER JOIN ... ON first.id = last.id,僅保留符合條件的匹配列。
mysql> SELECT first.*, last.* FROM first LEFT JOIN last ON first.id = last.id;
+------+------------+------+-----------+
| id | first_name | id | last_name |
+------+------------+------+-----------+
| 1 | Tom | NULL | NULL |
| 2 | Marry | 2 | Stone |
| 3 | Jarry | 3 | White |
+------+------------+------+-----------+
語法對稱,保留右表所有列。實務上習慣統一用 LEFT JOIN,透過調換表順序達成同等效果。
INNER JOIN/LEFT JOIN ... ON 語法,避免舊式逗號連接易漏寫 WHERE 導致全連接災難。SELECT *),減少網路傳輸與記憶體壓力。