CodeGym /課程 /SQL SELF /用 SELF JOIN 來自我合併資料

用 SELF JOIN 來自我合併資料

SQL SELF
等級 12 , 課堂 3
開放

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 Atable_name B 是同一張表,只是別名不一樣。
  • A.common_columnB.common_column 是用來合併紀錄的欄位。

別名(AB)就是讓 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 的「自拍」功能很實用啦!

留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION