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

SQL Server JOIN 類型完整圖解:CROSS、INNER、OUTER、SELF、FULL 與 HASH/MERGE 提示

     編輯:關於SqlServer

JOIN 分類總覽

類型關鍵字語意典型用途
交叉聯結CROSS JOIN笛卡兒積 (所有組合)測試資料生成、矩陣運算
內部聯結[INNER] JOIN雙邊符合條件的列最常用,主從表關聯
左外部聯結LEFT [OUTER] JOIN左表全保留,右表無配對填 NULL主表帶明細、報表列表
右外部聯結RIGHT [OUTER] JOIN右表全保留,左表無配對填 NULL較少用,可改 LEFT JOIN 交換順序
完整外部聯結FULL [OUTER] JOIN雙邊全保留,無配對填 NULL雙向差異比對、資料核對
自我聯結JOIN 同一表別名表內部行與行比較階層結構、同事入職日期比對

關鍵語法範例

LEFT JOIN 條件前置寫法 (效能較佳)


-- 寫法 A:ON 中混合聯結與篩選
SELECT a.cust_id, b.order_date, b.tot_amt
FROM customer a LEFT JOIN sales b
  ON a.cust_id = b.cust_id AND b.order_date > '1996/10/15';

-- 寫法 B:衍生表預先篩選 (推薦,減少外部聯結後再篩選)
SELECT a.cust_id, b.order_date, b.tot_amt
FROM customer a
LEFT JOIN (SELECT * FROM sales WHERE order_date > '1996/10/15') b
  ON a.cust_id = b.cust_id;

SELF JOIN 避免重複行


SELECT a.emp_no, a.emp_name, b.emp_no, b.emp_name, a.date_hired
FROM employee a JOIN employee b
  ON a.emp_no <> b.emp_no AND a.date_hired = b.date_hired
WHERE a.emp_name > b.emp_name;  -- 只取一邊,消除鏡像重複

FULL JOIN 實現雙欄位並排顯示 (面試題)


-- 表:id, ic, name, amount (ic='i' 收入, 'c' 支出)
-- 目標:收入與支出按序號並排
SELECT aaa.*, bbb.*
FROM (
    SELECT (SELECT COUNT(id) FROM aa b WHERE b.id < a.id AND ic='i') AS seq, *
    FROM aa a WHERE ic='i'
) aaa
FULL JOIN (
    SELECT (SELECT COUNT(id) FROM aa b WHERE b.id < a.id AND ic='c') AS seq, *
    FROM aa a WHERE ic='c'
) bbb ON aaa.seq = bbb.seq
ORDER BY aaa.name;

JOIN HINT:強制 HASH / MERGE 聯結


USE pubs;
SELECT SUBSTRING(RTRIM(a.au_fname)+' '+LTRIM(a.au_lname),1,25) AS Name,
       SUBSTRING(t.title,1,20) AS Title
FROM authors a 
INNER MERGE JOIN titleauthor ta ON a.au_id = ta.au_id
INNER HASH JOIN titles t ON t.title_id = ta.title_id
ORDER BY au_lname, au_fname;
  • MERGE JOIN:雙邊已排序 (或有索引順序),適合大表等值聯結,低記憶體
  • HASH JOIN:建立雜湊表再探測,適合大表無序、非等值或大小表差異大
  • 使用 Hint 後 INNER 關鍵字成為必填
  • 慎用:最佳化器通常比人更聰明,Hint 會隨統計資料變更而失效

實務建議:
1. 習慣用 LEFT JOIN 統一風格,避免 RIGHT JOIN 造成閱讀困擾。
2. 外部聯結的篩選條件**盡量放在 ON 子句**,而非 WHERE,否則隱性轉為內部聯結。
3. 大表聯結前確認聯結欄位有索引,觀察 Execution Plan 確認運算子 (Nested Loops / Merge / Hash)。

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