SQL JOIN 完整教學:INNER、LEFT、RIGHT、FULL JOIN 圖解【2026】
重點摘要
JOIN 用途:合併多個關聯表格的共同欄位查詢
INNER JOIN 僅回傳兩表都有匹配的交集資料
LEFT JOIN 保留左表全部,補上右表匹配資料
FULL OUTER JOIN 回傳兩表所有資料,含 NULL
CROSS JOIN 產生笛卡爾積,慎用避免效能爆炸
Self Join 讓同一表格自我關聯,適合階層查詢
在實際的資料庫應用中,資料通常分散在多個關聯表格中。例如,客戶資料存在「客戶表」、訂單資料存在「訂單表」、商品資料存在「商品表」。當你需要查詢「某客戶購買了哪些商品」時,就必須將這些表格「連接」起來查詢——這就是 SQL JOIN 的核心用途。
本文將以圖解方式完整介紹 SQL JOIN 的所有類型,搭配實際程式碼範例,幫助你直觀理解每種 JOIN 的差異與使用時機。無論你是剛學習 SQL 的新手,還是想複習 JOIN 語法的開發者,都能從本文獲得清晰的概念。
JOIN 概念與使用時機
什麼是 JOIN?
JOIN 是 SQL 中用於合併兩個或多個表格資料的操作。透過指定表格之間的關聯條件(通常是共同的欄位,如外鍵),JOIN 可以將分散的資料整合成一個查詢結果。
範例資料準備
為了清楚說明各種 JOIN 的差異,我們先建立兩個簡單的範例表格:
員工表(Employees):
EmployeeIDNameDepartmentID1Alice1012Bob1023Carol1014DavidNULL
部門表(Departments):
DepartmentIDDepartmentName101研發部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;
查詢結果:
EmployeeIDNameDepartmentName1Alice研發部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;
查詢結果:
EmployeeIDNameDepartmentName1Alice研發部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;
查詢結果:
DepartmentIDDepartmentNameName101研發部Alice101研發部Carol102行銷部Bob103財務部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;
查詢結果:
EmployeeIDNameDepartmentIDDepartmentName1Alice101研發部2Bob102行銷部3Carol101研發部4DavidNULLNULLNULLNULL103財務部
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 筆結果
NameDepartmentNameAlice研發部Alice行銷部Alice財務部Bob研發部Bob行銷部Bob財務部......
使用時機
產生所有可能的組合
測試資料生成
例如:產生「所有尺寸 × 所有顏色」的商品組合
注意: CROSS JOIN 會產生大量資料(m × n 列),使用時務必謹慎,避免對大型表格使用。
Self Join 自連接
Self Join 是表格與自己連接的特殊應用,用於處理具有層級關係的資料(如員工與主管、分類與子分類)。
範例資料
員工表(含主管欄位):
EmployeeIDNameManagerID1AliceNULL2Bob13Carol14David2
實際範例
-- 查詢每位員工及其主管姓名
SELECT
e.Name AS EmployeeName,
m.Name AS ManagerName
FROM Employees e
LEFT JOIN Employees m
ON e.ManagerID = m.EmployeeID;
查詢結果:
EmployeeNameManagerNameAliceNULLBobAliceCarolAliceDavidBob
使用時機
表格中有自我參照的關聯(如 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 完整指南:從入門到精通的資料庫查詢語言教學
SQL 語法大全:SELECT、JOIN、WHERE 完整查詢指令教學
SQL CRUD 操作完整指南:INSERT、UPDATE、DELETE 語法教學
SQL 函數完整指南:字串、日期、數學、聚合函數總整理
進階查詢技巧:
SQL 子查詢完整教學:Subquery 語法與實戰應用
SQL Window Function 教學:ROW_NUMBER、RANK、LAG 實戰應用
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 →
參考資料
W3Schools SQL JOIN - https://www.w3schools.com/sql/sql_join.asp
Microsoft SQL JOIN Documentation - https://docs.microsoft.com/sql/t-sql/queries/from-transact-sql
PostgreSQL JOIN Types - https://www.postgresql.org/docs/current/queries-table-expressions.html
MySQL JOIN Syntax - https://dev.mysql.com/doc/refman/8.0/en/join.html