返回首頁SQL

SQL JOIN 完整教學:INNER、LEFT、RIGHT、FULL JOIN 圖解【2025】

17 min 分鐘閱讀

SQL JOIN 完整教學:INNER、LEFT、RIGHT、FULL JOIN 圖解【2025】

SQL JOIN 完整教學:INNER、LEFT、RIGHT、FULL JOIN 圖解【2025】

在實際的資料庫應用中,資料通常分散在多個關聯表格中。例如,客戶資料存在「客戶表」、訂單資料存在「訂單表」、商品資料存在「商品表」。當你需要查詢「某客戶購買了哪些商品」時,就必須將這些表格「連接」起來查詢——這就是 SQL JOIN 的核心用途。

本文將以圖解方式完整介紹 SQL JOIN 的所有類型,搭配實際程式碼範例,幫助你直觀理解每種 JOIN 的差異與使用時機。無論你是剛學習 SQL 的新手,還是想複習 JOIN 語法的開發者,都能從本文獲得清晰的概念。

插圖:SQL JOIN 類型總覽圖,以 Venn Diagram 展示各種 JOIN 的資料選取範圍

場景描述: 並排展示 INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL OUTER JOIN 四種 JOIN 類型的 Venn Diagram,用不同顏色標示各類型選取的資料範圍。

視覺重點:

  • 主要內容清晰呈現

必須出現的元素:

  • 依據描述中的關鍵元素

需要顯示的中文字:

顏色調性: 專業、清晰

避免元素: 抽象圖形、齒輪、發光特效

Slug: sql-join-types-venn-diagram-overview


JOIN 概念與使用時機

什麼是 JOIN?

JOIN 是 SQL 中用於合併兩個或多個表格資料的操作。透過指定表格之間的關聯條件(通常是共同的欄位,如外鍵),JOIN 可以將分散的資料整合成一個查詢結果。

範例資料準備

為了清楚說明各種 JOIN 的差異,我們先建立兩個簡單的範例表格:

員工表(Employees):

EmployeeIDNameDepartmentID
1Alice101
2Bob102
3Carol101
4DavidNULL

部門表(Departments):

DepartmentIDDepartmentName
101研發部
102行銷部
103財務部

注意:David 沒有指定部門(DepartmentID 為 NULL),而財務部(103)沒有任何員工。

JOIN 類型總覽

JOIN 類型說明回傳資料
INNER JOIN內連接只回傳兩表都有匹配的資料
LEFT JOIN左外連接回傳左表所有資料 + 右表匹配資料
RIGHT JOIN右外連接回傳右表所有資料 + 左表匹配資料
FULL OUTER JOIN完全外連接回傳兩表所有資料
CROSS JOIN交叉連接回傳兩表的笛卡爾積
Self Join自連接表格與自己連接

INNER JOIN 內連接

INNER JOIN 是最常用的 JOIN 類型,只回傳兩個表格中都有匹配資料的列。如果某一邊沒有對應的資料,該列就不會出現在結果中。

語法結構

SELECT 欄位列表
FROM 表格A
INNER JOIN 表格B
ON 表格A.關聯欄位 = 表格B.關聯欄位;

圖解說明

    表格A              表格B
  ┌───────┐          ┌───────┐
  │       │          │       │
  │   ████████████████████   │
  │   █  交集部分  █   │
  │   ████████████████████   │
  │       │          │       │
  └───────┘          └───────┘

  INNER JOIN 只回傳交集部分(兩邊都有匹配的資料)

實際範例

-- 查詢所有有部門的員工及其部門名稱
SELECT
    e.EmployeeID,
    e.Name,
    d.DepartmentName
FROM Employees e
INNER JOIN Departments d
ON e.DepartmentID = d.DepartmentID;

查詢結果:

EmployeeIDNameDepartmentName
1Alice研發部
2Bob行銷部
3Carol研發部

說明: David 因為沒有部門(DepartmentID 為 NULL),所以不會出現在結果中。財務部因為沒有員工,也不會出現。

使用時機

  • 只需要兩個表格中都有對應資料的記錄
  • 排除任一表格中沒有匹配的資料
  • 例如:查詢「有訂單的客戶」、「已分配部門的員工」

LEFT JOIN 左外連接

LEFT JOIN(或 LEFT OUTER JOIN)回傳左表的所有資料,以及右表中匹配的資料。如果右表沒有匹配,則對應欄位顯示 NULL。

語法結構

SELECT 欄位列表
FROM 表格A
LEFT JOIN 表格B
ON 表格A.關聯欄位 = 表格B.關聯欄位;

圖解說明

    表格A              表格B
  ┌───────┐          ┌───────┐
  │███████│          │       │
  │███████████████████████   │
  │███████  交集  ████   │
  │███████████████████████   │
  │███████│          │       │
  └───────┘          └───────┘

  LEFT JOIN 回傳左表全部 + 交集部分

實際範例

-- 查詢所有員工及其部門(包含沒有部門的員工)
SELECT
    e.EmployeeID,
    e.Name,
    d.DepartmentName
FROM Employees e
LEFT JOIN Departments d
ON e.DepartmentID = d.DepartmentID;

查詢結果:

EmployeeIDNameDepartmentName
1Alice研發部
2Bob行銷部
3Carol研發部
4DavidNULL

說明: David 雖然沒有部門,但因為他在左表(Employees)中,所以會出現在結果中,DepartmentName 顯示為 NULL。

找出沒有匹配的資料

LEFT JOIN 常用於找出「左表有但右表沒有」的資料:

-- 查詢沒有分配部門的員工
SELECT
    e.EmployeeID,
    e.Name
FROM Employees e
LEFT JOIN Departments d
ON e.DepartmentID = d.DepartmentID
WHERE d.DepartmentID IS NULL;

結果: 只會回傳 David

使用時機

  • 需要保留左表所有資料,即使右表沒有對應
  • 找出「沒有關聯資料」的記錄
  • 例如:查詢「所有客戶及其訂單(含無訂單客戶)」、「所有商品及其銷售記錄(含未銷售商品)」

RIGHT JOIN 右外連接

RIGHT JOIN(或 RIGHT OUTER JOIN)與 LEFT JOIN 相反,回傳右表的所有資料,以及左表中匹配的資料。

語法結構

SELECT 欄位列表
FROM 表格A
RIGHT JOIN 表格B
ON 表格A.關聯欄位 = 表格B.關聯欄位;

圖解說明

    表格A              表格B
  ┌───────┐          ┌───────┐
  │       │          │███████│
  │   ███████████████████████│
  │   ████  交集  ███████│
  │   ███████████████████████│
  │       │          │███████│
  └───────┘          └───────┘

  RIGHT JOIN 回傳交集部分 + 右表全部

實際範例

-- 查詢所有部門及其員工(包含沒有員工的部門)
SELECT
    d.DepartmentID,
    d.DepartmentName,
    e.Name
FROM Employees e
RIGHT JOIN Departments d
ON e.DepartmentID = d.DepartmentID;

查詢結果:

DepartmentIDDepartmentNameName
101研發部Alice
101研發部Carol
102行銷部Bob
103財務部NULL

說明: 財務部(103)雖然沒有員工,但因為它在右表(Departments)中,所以會出現在結果中。

實務建議

在實務上,大多數開發者偏好使用 LEFT JOIN,因為閱讀順序更直觀(先看主表,再看關聯表)。RIGHT JOIN 通常可以透過調換表格順序改寫成 LEFT JOIN:

-- 以下兩個查詢結果相同
-- 使用 RIGHT JOIN
SELECT * FROM Employees e RIGHT JOIN Departments d ON e.DepartmentID = d.DepartmentID;

-- 改寫為 LEFT JOIN(推薦)
SELECT * FROM Departments d LEFT JOIN Employees e ON d.DepartmentID = e.DepartmentID;

FULL OUTER JOIN 完全外連接

FULL OUTER JOIN 回傳兩個表格的所有資料,無論是否有匹配。沒有匹配的部分顯示 NULL。

語法結構

SELECT 欄位列表
FROM 表格A
FULL OUTER JOIN 表格B
ON 表格A.關聯欄位 = 表格B.關聯欄位;

注意: MySQL 不直接支援 FULL OUTER JOIN,需要使用 UNION 模擬。

圖解說明

    表格A              表格B
  ┌───────┐          ┌───────┐
  │███████│          │███████│
  │███████████████████████████│
  │███████  交集  ███████│
  │███████████████████████████│
  │███████│          │███████│
  └───────┘          └───────┘

  FULL OUTER JOIN 回傳兩個表格的所有資料

實際範例

-- SQL Server / PostgreSQL 語法
SELECT
    e.EmployeeID,
    e.Name,
    d.DepartmentID,
    d.DepartmentName
FROM Employees e
FULL OUTER JOIN Departments d
ON e.DepartmentID = d.DepartmentID;

查詢結果:

EmployeeIDNameDepartmentIDDepartmentName
1Alice101研發部
2Bob102行銷部
3Carol101研發部
4DavidNULLNULL
NULLNULL103財務部

MySQL 模擬 FULL OUTER JOIN

-- MySQL 不支援 FULL OUTER JOIN,使用 UNION 模擬
SELECT e.EmployeeID, e.Name, d.DepartmentID, d.DepartmentName
FROM Employees e
LEFT JOIN Departments d ON e.DepartmentID = d.DepartmentID

UNION

SELECT e.EmployeeID, e.Name, d.DepartmentID, d.DepartmentName
FROM Employees e
RIGHT JOIN Departments d ON e.DepartmentID = d.DepartmentID;

使用時機

  • 需要完整呈現兩個表格的所有資料
  • 分析兩個資料集的差異
  • 例如:比對兩個系統的資料完整性

CROSS JOIN 交叉連接

CROSS JOIN 產生兩個表格的笛卡爾積(Cartesian Product),即左表每一列與右表每一列的所有組合。

語法結構

-- 語法一:明確使用 CROSS JOIN
SELECT 欄位列表
FROM 表格A
CROSS JOIN 表格B;

-- 語法二:隱式寫法
SELECT 欄位列表
FROM 表格A, 表格B;

實際範例

-- 產生所有員工與所有部門的組合
SELECT
    e.Name,
    d.DepartmentName
FROM Employees e
CROSS JOIN Departments d;

查詢結果: 4 名員工 × 3 個部門 = 12 筆結果

NameDepartmentName
Alice研發部
Alice行銷部
Alice財務部
Bob研發部
Bob行銷部
Bob財務部
......

使用時機

  • 產生所有可能的組合
  • 測試資料生成
  • 例如:產生「所有尺寸 × 所有顏色」的商品組合

注意: CROSS JOIN 會產生大量資料(m × n 列),使用時務必謹慎,避免對大型表格使用。


Self Join 自連接

Self Join 是表格與自己連接的特殊應用,用於處理具有層級關係的資料(如員工與主管、分類與子分類)。

範例資料

員工表(含主管欄位):

EmployeeIDNameManagerID
1AliceNULL
2Bob1
3Carol1
4David2

實際範例

-- 查詢每位員工及其主管姓名
SELECT
    e.Name AS EmployeeName,
    m.Name AS ManagerName
FROM Employees e
LEFT JOIN Employees m
ON e.ManagerID = m.EmployeeID;

查詢結果:

EmployeeNameManagerName
AliceNULL
BobAlice
CarolAlice
DavidBob

使用時機

  • 表格中有自我參照的關聯(如 ManagerID 指向同表的 EmployeeID)
  • 處理層級結構資料
  • 例如:組織架構、商品分類、留言回覆

多表 JOIN 與效能考量

多表 JOIN 語法

實務中經常需要連接三個以上的表格:

-- 查詢訂單明細:客戶名稱、訂單編號、商品名稱
SELECT
    c.CustomerName,
    o.OrderID,
    o.OrderDate,
    p.ProductName,
    od.Quantity
FROM Customers c
INNER JOIN Orders o ON c.CustomerID = o.CustomerID
INNER JOIN OrderDetails od ON o.OrderID = od.OrderID
INNER JOIN Products p ON od.ProductID = p.ProductID
WHERE o.OrderDate >= '2025-01-01';

JOIN 效能優化建議

優化方向說明
建立索引在 JOIN 欄位(通常是外鍵)建立索引
先篩選再 JOIN使用 WHERE 或子查詢先縮小資料範圍
**避免 SELECT ***只選取需要的欄位,減少資料傳輸
小表驅動大表將資料量小的表格放在 JOIN 左邊
檢視執行計畫使用 EXPLAIN 分析查詢效能
-- 建立索引範例
CREATE INDEX idx_orders_customerid ON Orders(CustomerID);
CREATE INDEX idx_orderdetails_orderid ON OrderDetails(OrderID);

常見問題 FAQ

Q1:LEFT JOIN 和 RIGHT JOIN 有什麼差別?

LEFT JOIN 保留左邊表格的所有資料,RIGHT JOIN 保留右邊表格的所有資料。以 FROM A LEFT JOIN B 為例,即使 B 表沒有對應資料,A 表的資料仍會全部出現,B 表欄位顯示 NULL。反之,FROM A RIGHT JOIN B 會保留 B 表所有資料。實務上,大多數開發者習慣使用 LEFT JOIN,因為閱讀順序更直觀(主表在前)。如果需要 RIGHT JOIN 的效果,可以調換表格順序改用 LEFT JOIN。

Q2:什麼時候應該使用 INNER JOIN?

當你只需要兩個表格中都有對應資料的記錄時,使用 INNER JOIN。例如:查詢「有訂單的客戶」——如果某客戶沒有訂單,你不希望他出現在結果中,就使用 INNER JOIN。相反地,如果你需要「所有客戶,包含沒有訂單的」,就應該使用 LEFT JOIN。簡單判斷:如果你可以接受某些列因為沒有匹配而「消失」,就用 INNER JOIN;如果你需要保留某一邊的完整資料,就用 LEFT/RIGHT JOIN。


延伸學習資源

深入學習 SQL 查詢技巧,建議參考以下資源:

SQL 基礎語法:

進階查詢技巧:


結論

SQL JOIN 是資料庫查詢的核心技能,掌握各種 JOIN 類型的差異,能讓你靈活處理各種多表查詢需求。簡單總結:

  • INNER JOIN:只要交集,兩邊都有才回傳
  • LEFT JOIN:保留左表全部,右表沒有則顯示 NULL
  • RIGHT JOIN:保留右表全部,左表沒有則顯示 NULL
  • FULL OUTER JOIN:兩邊全部保留
  • CROSS JOIN:產生所有組合(笛卡爾積)
  • Self Join:表格與自己連接,處理層級關係

建議從 INNER JOIN 和 LEFT JOIN 開始練習,這兩種涵蓋了 90% 以上的實務需求。熟練後再學習其他 JOIN 類型,逐步提升你的 SQL 查詢能力。


想要快速查閱 JOIN 語法? — 下載我們整理的 SQL JOIN 速查圖解,包含所有 JOIN 類型的 Venn Diagram 與語法範例,列印出來放在桌邊隨時參考。

免費下載 SQL JOIN 速查圖解 PDF →


參考資料

需要專業的雲端建議?

無論您正在評估雲平台、優化現有架構,或尋找節費方案,我們都能提供協助

預約免費諮詢

相關文章