SELF JOIN 就是把一張表跟自己 JOIN 起來。剛開始看可能會覺得怪怪的:為什麼要自己跟自己合併?但現實中這種需求其實蠻常見的。比如說,你有一張員工表,每個員工都有個 manager。manager 其實也是員工,所以他的資料也在同一張表裡。這時候 SELF JOIN 就能幫我們把員工跟他們的 manager 對起來。
如果要講正式一點,SELF JOIN 其實就是一般的 JOIN,只是我們把同一張表用兩次,給它不同的別名(alias),這樣就能分清楚「兩個版本」的表。
SELF JOIN 可以用來:
- 階層關係:建立「父子」關係,比如員工跟他的 manager。
- 分析表內資料:比對同一張表裡的紀錄,比如找相似的商品或事件。
- 處理有重複邏輯的複雜查詢。
SELF JOIN 的語法
直接來看個簡單的 SELF JOIN 語法範例:
SELECT
A.column_name,
B.column_name
FROM
table_name A
JOIN
table_name B
ON
A.common_column = B.common_column;
這裡:
table_name A跟table_name B是同一張表,只是別名不一樣。A.common_column跟B.common_column是用來合併紀錄的欄位。
別名(A 跟 B)就是讓 DBMS 能分辨你現在在用哪個「版本」的表。
SELF JOIN 的使用範例
範例 1:員工和他們的 manager 清單
假設我們有一張 employees 表,長這樣:
| employee_id | name | manager_id |
|---|---|---|
| 1 | Alex Lin | NULL |
| 2 | Maria Chi | 1 |
| 3 | Otto Song | 1 |
| 4 | Nina Zhao | 2 |
這張表裡:
employee_id— 員工的 ID。name— 員工名字。manager_id— manager 的 ID,其實就是另一個員工的employee_id。
目標:查出員工和他們的 manager。
用 SELF JOIN 來解決:
SELECT
e.name AS employee_name,
m.name AS manager_name
FROM
employees e
LEFT JOIN
employees m
ON
e.manager_id = m.employee_id;
結果:
| employee_name | manager_name |
|---|---|
| Alex Lin | NULL |
| Maria Chi | Alex Lin |
| Otto Song | Alex Lin |
| Nina Zhao | Maria Chi |
這裡:
- 表
e是「員工」。 - 表
m也是「員工」,但這次是當「manager」。
Alex Lin 沒有 manager(manager_id = NULL),所以 manager_name 會是空的。
範例 2:找相似商品
假設我們有一張 products 表:
| product_id | product_name | category |
|---|---|---|
| 1 | 冰箱 | 家電 |
| 2 | 洗衣機 | 家電 |
| 3 | 智慧型手機 | 小工具 |
| 4 | 平板 | 小工具 |
目標:找出同一個類別的商品配對。
用 SELF JOIN 來解:
SELECT
p1.product_name AS product_1,
p2.product_name AS product_2
FROM
products p1
JOIN
products p2
ON
p1.category = p2.category
AND
p1.product_id < p2.product_id;
結果:
| product_1 | product_2 |
|---|---|
| 冰箱 | 洗衣機 |
| 智慧型手機 | 平板 |
注意 p1.product_id < p2.product_id 這個條件。這樣可以避免重複配對,比如不會出現「冰箱 — 洗衣機」和「洗衣機 — 冰箱」兩種。
範例 3:分析階層(父類別和子類別)
再來一個例子。假設有一張 categories 表:
| category_id | category_name | parent_id |
|---|---|---|
| 1 | 家電 | NULL |
| 2 | 小工具 | 1 |
| 3 | 電腦 | 1 |
| 4 | 智慧型手機 | 2 |
這裡:
category_id— 類別的 ID。category_name— 類別名稱。parent_id— 父類別的 ID。
目標:把類別和它們的父類別對起來。
查詢:
SELECT
c1.category_name AS child_category,
c2.category_name AS parent_category
FROM
categories c1
LEFT JOIN
categories c2
ON
c1.parent_id = c2.category_id;
結果:
| child_category | parent_category |
|---|---|
| 家電 | NULL |
| 小工具 | 家電 |
| 電腦 | 家電 |
| 智慧型手機 | 小工具 |
用 SELF JOIN 常見的錯誤
忘記加 alias(別名): 如果沒用 alias,根本分不清是哪個「版本」的表。
循環參照: 如果資料有循環參照(比如員工自己當自己的 manager),結果可能會怪怪的。
結果重複: 記得要過濾結果(像用 p1.product_id < p2.product_id),不然會有重複。
SELF JOIN 超強大,學會用它可以解決很多階層、表內關聯、資料分析的問題。希望你現在也覺得這個 SQL 的「自拍」功能很實用啦!
GO TO FULL VERSION