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

SQL 多表查詢語法大全:內聯結、外聯結、交叉聯結與自我聯結實例

     編輯:關於SqlServer

多表查詢是關聯式資料庫威力所在。本文系統整理 INNER JOIN、LEFT/RIGHT/FULL OUTER JOIN、CROSS JOIN、自我聯結 語法與實戰範例,並說明 WHERE 舊式聯結與 JOIN ... ON 標準語法的差異。

基本聯結類型對照

聯結類型關鍵字結果集包含適用場景
內聯結INNER JOIN / JOIN雙方皆符合條件的列主流查詢:訂單+明細、員工+部門
左外聯結LEFT [OUTER] JOIN左表所有列 + 右表匹配列 (無匹配為 NULL)報表需保留主表:所有客戶+訂單(含無訂單)
右外聯結RIGHT [OUTER] JOIN右表所有列 + 左表匹配列較少用,可改 LEFT JOIN 交換表順序
完整外聯結FULL [OUTER] JOIN雙方所有列,無匹配處為 NULL雙向對帳:兩系統資料比對
交叉聯結CROSS JOIN笛卡兒積:左表列數 × 右表列數產生完整維度組合 (見 CROSS JOIN 專文)

標準語法 (ANSI SQL-92) — 推薦

SELECT select_list
FROM table_a a
INNER JOIN table_b b ON a.common_col = b.common_col
LEFT JOIN table_c c ON b.other_col = c.other_col
WHERE a.filter_col = 'value';
  • 聯結條件放在 ON,篩選條件放在 WHERE,語意清晰、優化器易處理。
  • 同名欄位必須加表別名限定 (如 a.id)。

舊式語法 (WHERE 聯結) — 不推薦

SELECT a.col1, b.col2
FROM table_a a, table_b b
WHERE a.id = b.id
  AND a.status = 1;
  • 外聯結需用 (+) (Oracle) 或 *= (SQL Server 舊版),已淘汰、不可攜、易出錯。
  • SQL Server 2012+ 已移除 *= =* 支援。

實戰範例

1. 內聯結:電影 + 影碟庫存

SELECT 
    m.MovieID, m.MovieName, m.MovieType, m.Brief,
    d.DiscID, d.DiscState, d.DiscType, d.Remarks
FROM Movies m
INNER JOIN Discs d ON m.MovieID = d.MovieID
WHERE m.MovieType = N'動作';

2. 左外聯結:所有客戶 + 訂單 (含無訂單客戶)

SELECT c.CustomerID, c.CompanyName, o.OrderID, o.OrderDate
FROM Customers c
LEFT JOIN Orders o ON c.CustomerID = o.CustomerID
ORDER BY c.CompanyName;

3. 自我聯結:員工與主管

SELECT e.EmpName AS Employee, m.EmpName AS Manager
FROM Employees e
LEFT JOIN Employees m ON e.ManagerID = m.EmpID
ORDER BY Manager, Employee;

4. 多表聯結:公司 + 員工 + 部門 + 薪資等級

SELECT 
    c.CompanyName,
    e.EmpName,
    d.DeptName,
    s.Grade, s.MinSalary, s.MaxSalary
FROM Companies c
INNER JOIN Employees e ON c.CompanyID = e.CompanyID
INNER JOIN Departments d ON e.DeptID = d.DeptID
INNER JOIN SalaryGrades s ON e.Salary BETWEEN s.MinSalary AND s.MaxSalary
WHERE c.Country = N'Taiwan';

5. 條件彙總:各類別商品數量與總庫存

SELECT 
    cat.CategoryName,
    COUNT(p.ProductID) AS ProductCount,
    SUM(p.UnitsInStock) AS TotalStock
FROM Categories cat
LEFT JOIN Products p ON cat.CategoryID = p.CategoryID
GROUP BY cat.CategoryName
ORDER BY TotalStock DESC;

效能與寫作建議

  1. 小表驅動大表:將篩選後較小的結果集放在聯結順序前方 (優化器通常會自動重排,但可用 Hint 強制)。
  2. 聯結欄位建立索引:FK、PK、常用聯結鍵必須有索引。
  3. 避免在 ON 條件使用函數:ON UPPER(a.col) = UPPER(b.col) 導致索引失效,改用計算欄位/持久化計算欄位。
  4. 只選需要的欄位:SELECT * 增加網路傳輸、記憶體、暫存表壓力。
  5. 必要時才用外聯結:見「避免 LEFT JOIN」專文。

Oracle (+) 舊語法對應表 (僅供維護舊系統參考)

ANSIOracle (+)
LEFT JOIN b ON a.id = b.ida.id = b.id(+)
RIGHT JOIN b ON a.id = b.ida.id(+) = b.id
FULL JOIN不支援 (需 UNION 兩邊外聯結)

掌握標準 JOIN ... ON 語法,能撰寫可攜、可讀、高效能的多表查詢,是 SQL 開發者必備核心技能。

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