CROSS JOIN 關鍵字 (SQL CROSS JOIN) - 交叉連接
CROSS JOIN (交叉連接) 會產生兩個資料表的笛卡兒乘積 (Cartesian Product),也就是將第一個資料表的每一筆記錄與第二個資料表的每一筆記錄組合在一起。
如果左表有 M 筆記錄,右表有 N 筆記錄,CROSS JOIN 的結果會有 M × N 筆記錄。
⚠️ 注意: CROSS JOIN 會產生大量的結果資料。如果兩個表各有 1000 筆記錄,CROSS JOIN 會產生 1,000,000 筆結果。在實際應用中要謹慎使用。
CROSS JOIN 語法 (Syntax)
標準語法:
SELECT column_list
FROM table1
CROSS JOIN table2;
隱式語法 (逗號分隔):
SELECT column_list
FROM table1, table2;
當在 FROM 子句中使用逗號分隔多個資料表,且沒有指定 WHERE 條件時,效果等同於 CROSS JOIN。
MySQL 的替代語法:
SELECT column_list
FROM table1
JOIN table2;
在 MySQL 中,不帶 ON 條件的 JOIN 也會執行 CROSS JOIN。
CROSS JOIN 用法範例 (Example)
customers 資料表:
| C_Id | Name |
|---|---|
| 1 | 張一 |
| 2 | 王二 |
| 3 | 李三 |
products 資料表:
| P_Id | Product |
|---|---|
| A | 滑鼠 |
| B | 鍵盤 |
範例: 使用 CROSS JOIN 產生所有客戶與所有產品的組合。
SELECT customers.Name, products.Product
FROM customers
CROSS JOIN products;
結果: (3 × 2 = 6 筆)
| Name | Product |
|---|---|
| 張一 | 滑鼠 |
| 張一 | 鍵盤 |
| 王二 | 滑鼠 |
| 王二 | 鍵盤 |
| 李三 | 滑鼠 |
| 李三 | 鍵盤 |
CROSS JOIN 的實際應用
雖然 CROSS JOIN 產生的資料量很大,但它在某些情況下非常有用:
1. 產生所有可能的組合
範例: 產生所有尺寸和顏色的組合。
-- sizes 資料表:S, M, L
-- colors 資料表:紅, 藍, 綠
SELECT sizes.Size, colors.Color
FROM sizes
CROSS JOIN colors;
結果會產生 9 種組合 (S-紅, S-藍, S-綠, M-紅, M-藍, M-綠, L-紅, L-藍, L-綠)。
2. 建立日期或時間表
範例: 產生一週內每小時的時間表。
-- days:Mon, Tue, Wed, Thu, Fri
-- hours:9, 10, 11, 12, 13, 14, 15, 16, 17
SELECT days.Day, hours.Hour
FROM days
CROSS JOIN hours;
3. 資料分析中的基準表
當需要確保每個類別都有資料時,可以用 CROSS JOIN 建立基準表,再與實際資料進行 LEFT JOIN。
-- 確保每個客戶的每個月份都有記錄(即使是 0)
SELECT customers.C_Id, months.Month, COALESCE(SUM(orders.Amount), 0) AS Total
FROM customers
CROSS JOIN months
LEFT JOIN orders ON customers.C_Id = orders.C_Id AND months.Month = MONTH(orders.Order_Date)
GROUP BY customers.C_Id, months.Month;
CROSS JOIN vs 其他 JOIN
| 特性 | CROSS JOIN | INNER/LEFT/RIGHT/FULL JOIN |
|---|---|---|
| ON 條件 | 不需要 | 需要 |
| 結果數量 | M × N | 取決於匹配條件 |
| 用途 | 產生所有組合 | 關聯相關資料 |
CROSS JOIN 加上 WHERE 條件
如果在 CROSS JOIN 後加上 WHERE 條件來篩選結果,其效果等同於 INNER JOIN:
-- 這兩個查詢結果相同
SELECT customers.Name, orders.Order_No
FROM customers
CROSS JOIN orders
WHERE customers.C_Id = orders.C_Id;
SELECT customers.Name, orders.Order_No
FROM customers
INNER JOIN orders ON customers.C_Id = orders.C_Id;
然而,為了程式碼的可讀性和明確性,當需要關聯條件時,建議使用 INNER JOIN 而非 CROSS JOIN + WHERE。
💡 效能提示: CROSS JOIN 會在產生完整的笛卡兒乘積後才套用 WHERE 條件,而 INNER JOIN 在連接過程中就會篩選資料。在處理大量資料時,INNER JOIN 通常更有效率。