首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server 聯合查詢完全指南:INNER/LEFT/RIGHT/FULL JOIN 語法、效能與實戰範例

     編輯:關於SqlServer

前言:為什麼要用明確 JOIN 語法?

舊式 WHERE t1.id = t2.id 隱性聯結雖然仍支援,但 ANSI SQL-92 標準的明確 JOIN 語法具備:

  • 可讀性:聯結條件與過濾條件分離,邏輯清晰。
  • 效能:查詢最佳化器更容易產生最佳執行計畫 (尤其複雜多表聯結)。
  • 外部聯結正確性:舊式 *= / =* 語法在複雜條件下易產生語意模糊,已被棄用。

一、四大聯結類型圖解與語法

以兩張表為例:

  • t1 (使用者):userid (PK), username, password
  • t3 (積分等級):userid (FK), jf (積分), dj (等級)

資料樣本:

t1.useridusernamepassword
1jackjackpwd
2owenowenpwd
t3.useridjfdj
1203
3506

1. 內部聯結 (INNER JOIN)

-- 推薦寫法
SELECT * FROM t1 INNER JOIN t3 ON t1.userid = t3.userid;

-- 舊式寫法 (等效但不推薦)
SELECT * FROM t1, t3 WHERE t1.userid = t3.userid;

結果:僅保留雙方都有的 userid=1。
特性:相當於集合交集,效能最好,最常用。

2. 左外部聯結 (LEFT OUTER JOIN)

SELECT * FROM t1 LEFT OUTER JOIN t3 ON t1.userid = t3.userid;

結果:保留左表 (t1) 所有列,右表無對應處顯示 NULL。
userid=2 (owen) 保留,t3 欄位為 NULL。

3. 右外部聯結 (RIGHT OUTER JOIN)

SELECT * FROM t1 RIGHT OUTER JOIN t3 ON t1.userid = t3.userid;

結果:保留右表 (t3) 所有列,左表無對應處顯示 NULL。
userid=3 (t3 獨有) 保留,t1 欄位為 NULL。

4. 完整外部聯結 (FULL OUTER JOIN)

SELECT * FROM t1 FULL OUTER JOIN t3 ON t1.userid = t3.userid;

結果:雙邊所有列皆保留,無對應處填 NULL。
相當於 LEFT JOIN UNION RIGHT JOIN。

二、效能考量與最佳化建議

面向 建議
聯結順序 讓最佳化器決定 (通常不需強制),但可用 OPTION (FORCE ORDER) 測試。
聯結欄位索引 聯結鍵 (ON 條件欄位) 必須有索引,否則掃描整表,效能災難。
篩選條件下推 WHERE 條件盡早套用,減少聯結輸入列數。內部聯結的 WHERE 與 ON 效果相同;外部聯結的 WHERE 會將外部聯結轉為內部聯結,需謹慎。
避免 SELECT * 僅選取所需欄位,減少網路傳輸、記憶體與 TempDB 壓力。
統計資料更新 定期 UPDATE STATISTICS 或啟用自動更新,確保最佳化器估算準確。

三、進階實戰模式

1. 多表鏈式聯結

SELECT o.OrderID, c.CustomerName, e.EmployeeName, d.ProductName
FROM Orders o
INNER JOIN Customers c ON o.CustomerID = c.CustomerID
INNER JOIN Employees e ON o.EmployeeID = e.EmployeeID
INNER JOIN OrderDetails od ON o.OrderID = od.OrderID
INNER JOIN Products d ON od.ProductID = d.ProductID;

2. 條件式外部聯結 (篩選放在 ON vs WHERE)

-- 正確:先聯結再篩選右表,保留左表所有列
SELECT * FROM t1 LEFT JOIN t3 ON t1.userid = t3.userid AND t3.jf > 30;

-- 錯誤:WHERE 篩選右表欄位,會把 NULL 列濾掉,變成內部聯結
SELECT * FROM t1 LEFT JOIN t3 ON t1.userid = t3.userid WHERE t3.jf > 30;

3. 自我聯結 (階層/遞迴結構)

SELECT e.EmployeeName AS Emp, m.EmployeeName AS Mgr
FROM Employees e
LEFT JOIN Employees m ON e.ManagerID = m.EmployeeID;

4. 衍生表/子查詢聯結

四、常見錯誤與除錯技巧

  • 資料重複:聯結鍵非唯一導致笛卡兒積。檢查 DISTINCT 或加強聯結條件。
  • NULL 值陷阱:NULL = NULL 為 UNKNOWN,不會聯結成功。外部聯結保留 NULL 列時,後續 WHERE 條件需用 IS NULL 判斷。
  • 隱性轉換:聯結欄位資料型別不符 (如 VARCHAR vs INT) 導致索引失效。統一型別或顯式 CAST。

結語

掌握四種 JOIN 的語意差異、效能特性與正確用法,是撰寫高效能 SQL 的核心技能。原則:預設用 INNER JOIN,需要保留單邊資料才用 LEFT/RIGHT JOIN,極少數情況用 FULL JOIN;永遠為聯結鍵建立索引,並讓統計資料保持最新。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved