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

SQL JOIN 完全指南:內聯接、外聯接 (LEFT/RIGHT/FULL)、交叉聯接語法與實戰範例

     編輯:關於SqlServer

資料庫設計遵循第三正規化 (3NF) 後,資料分散於多張關聯表,查詢需透過 JOIN 重組。本文系統整理 INNER JOIN、LEFT/RIGHT/FULL OUTER JOIN、CROSS JOIN 五大類型語法、語意差異、適用場景與效能建議,並說明為何推薦 FROM 子句寫法而非舊式 WHERE 聯接。

一、聯接寫法演進:WHERE vs FROM

舊式 WHERE 聯接 (不推薦)

SELECT A.SYMBOL, A.SNAME, B.TDATE, B.CLOSE
FROM SECURITYCODE A, DAYQUOTE B
WHERE A.SYMBOL = B.SYMBOL
  AND B.TDATE >= A.LISTDATE
  AND A.SYMBOL LIKE '600%';

缺點:聯接條件與篩選條件混雜、難以閱讀、外聯接語法 (*=, =*) 易產生歧義且已棄用。

標準 FROM 子句聯接 (推薦)

SELECT A.SYMBOL, A.SNAME, B.TDATE, B.CLOSE
FROM SECURITYCODE A
INNER JOIN DAYQUOTE B ON A.SYMBOL = B.SYMBOL
WHERE B.TDATE >= A.LISTDATE
  AND A.SYMBOL LIKE '600%'
ORDER BY A.SYMBOL, B.TDATE;

優點:聯接邏輯與篩選邏輯分離、支援完整外聯接語法、可讀性與維護性佳。

二、五大聯接類型完整對照

類型關鍵字回傳資料列典型用途Venn 圖
內聯接INNER JOIN / JOIN雙方皆符合條件的列主從表必然關聯 (訂單-明細)交集
左外聯接LEFT JOIN / LEFT OUTER JOIN左表所有列 + 右表匹配列 (無匹配則 NULL)主表保留、從表可選 (客戶-訂單)左圓完整
右外聯接RIGHT JOIN / RIGHT OUTER JOIN右表所有列 + 左表匹配列左外聯接反向,鮮用右圓完整
完整外聯接FULL JOIN / FULL OUTER JOIN雙表所有列,無匹配處填 NULL雙向保留、差異比對 (對帳)聯集
交叉聯接CROSS JOIN笛卡兒積 (左列數 × 右列數)產生組合矩陣、測試資料生成無重疊

三、外聯接進階:謂詞位置影響語意

外聯接中,ON 子句條件決定「如何匹配」,WHERE 子句條件決定「最終保留哪些列」。

-- 正確:篩選條件放在 ON,保留左表所有列
SELECT S.STOR_ID, S.QTY, T.TITLE
FROM SALES S
RIGHT JOIN TITLES T ON S.TITLE_ID = T.TITLE_ID AND S.QTY > 50;

-- 錯誤:放在 WHERE 會過濾掉右表無匹配列 (變成內聯接)
SELECT S.STOR_ID, S.QTY, T.TITLE
FROM SALES S
RIGHT JOIN TITLES T ON S.TITLE_ID = T.TITLE_ID
WHERE S.QTY > 50;  -- 導致 NULL 被過濾

四、效能與最佳實務

  • ✅ 優先使用 INNER JOIN,僅在業務真正需要保留單方所有列時用 LEFT JOIN。
  • ✅ 聯接欄位建立索引 (覆蓋索引更佳),避免 Hash Match / Nested Loops 退化為 Table Scan。
  • ✅ 避免在大表上使用 FULL JOIN,資料量爆炸;改用 UNION ALL 分別查再合併。
  • ✅ CROSS JOIN 僅用於小表 (如設定表、日期維度) 或刻意產生組合。
  • ✅ 多表聯接時,依選擇度 (Selectivity) 由小到大排列聯接順序,或依賴優化器重排 (通常可信)。

五、常見反模式與修正

反模式問題修正
WHERE 子句聯接 + *= 語法舊語法、易產生歧義、不支援 FULL JOIN改用 FROM ... LEFT JOIN
LEFT JOIN 後 WHERE 右表欄位 = 值隱性轉為 INNER JOIN條件移至 ON 子句
大量 CROSS JOIN 產生中繼結果TempDB 爆滿、記憶體壓力改用 APPLY / 窗口函數 / 分批處理
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved