實務開發中,單表無法滿足業務需求,必須透過關聯鍵(PK/FK)將多表組合。SQL Server 提供豐富的 JOIN 語法,本文以「學生借書」經典範例,詳細解析各類連接的語法、語意與結果差異。
| StudentID | StudentName | StudentAge |
|---|---|---|
| 1 | 張三 | 25 |
| 2 | 李四 | 26 |
| 3 | 王五 | 27 |
| 4 | 趙六 | 28 |
| 5 | 無名氏 | 27 |
| BorrowBookID | BorrowBookName | StudentID | BorrowBookPublish |
|---|---|---|---|
| 1 | 馬克思主義政治經濟學 | 1 | 電子工業出版社 |
| 2 | 毛澤東思想概論 | 2 | 高等教育出版社 |
| 3 | 鄧小平理論 | 3 | 人民郵電出版社 |
| 4 | 大學生思想道德修養 | 4 | 中國鐵道出版社 |
| 5 | C語言程序設計 | NULL | 高等教育出版社 |
關聯鍵:Student.StudentID = BorrowBook.StudentID
-- ANSI SQL-92 標準寫法(推薦)
SELECT s.StudentName, s.StudentAge, b.BorrowBookName, b.BorrowBookPublish
FROM Student s
INNER JOIN BorrowBook b ON s.StudentID = b.StudentID;
-- 舊式 WHERE 連接寫法(等價,不推薦新代碼使用)
SELECT s.StudentName, s.StudentAge, b.BorrowBookName, b.BorrowBookPublish
FROM Student s, BorrowBook b
WHERE s.StudentID = b.StudentID;
| StudentName | StudentAge | BorrowBookName | BorrowBookPublish |
|---|---|---|---|
| 張三 | 25 | 馬克思主義政治經濟學 | 電子工業出版社 |
| 李四 | 26 | 毛澤東思想概論 | 高等教育出版社 |
| 王五 | 27 | 鄧小平理論 | 人民郵電出版社 |
| 趙六 | 28 | 大學生思想道德修養 | 中國鐵道出版社 |
特徵:StudentID=5(無名氏)無借書紀錄 → 排除;BorrowBookID=5(C語言)StudentID 為 NULL → 排除。內連接等同於集合論的交集。
=,結果保留所有欄位(含重複鍵欄)。>, >=, <, <=, <>, != 等比較運算子。SELECT s.StudentName, s.StudentAge, b.BorrowBookName, b.BorrowBookPublish
FROM Student s
LEFT JOIN BorrowBook b ON s.StudentID = b.StudentID;
| StudentName | StudentAge | BorrowBookName | BorrowBookPublish |
|---|---|---|---|
| 張三 | 25 | 馬克思主義政治經濟學 | 電子工業出版社 |
| 李四 | 26 | 毛澤東思想概論 | 高等教育出版社 |
| 王五 | 27 | 鄧小平理論 | 人民郵電出版社 |
| 趙六 | 28 | 大學生思想道德修養 | 中國鐵道出版社 |
| 無名氏 | 27 | NULL | NULL |
語意:以左表為主,右表無匹配則以 NULL 填補。常用於「主表全保留、明細表可選」場景(如:所有學生及其借書情況,含未借書者)。
SELECT s.StudentName, s.StudentAge, b.BorrowBookName, b.BorrowBookPublish
FROM Student s
RIGHT JOIN BorrowBook b ON s.StudentID = b.StudentID;
| StudentName | StudentAge | BorrowBookName | BorrowBookPublish |
|---|---|---|---|
| 張三 | 25 | 馬克思主義政治經濟學 | 電子工業出版社 |
| 李四 | 26 | 毛澤東思想概論 | 高等教育出版社 |
| 王五 | 27 | 鄧小平理論 | 人民郵電出版社 |
| 趙六 | 28 | 大學生思想道德修養 | 中國鐵道出版社 |
| NULL | NULL | C語言程序設計 | 高等教育出版社 |
語意:以右表為主,左表無匹配則 NULL。實務較少用,可改寫為 LEFT JOIN 交換表順序以利閱讀。
SELECT s.StudentName, s.StudentAge, b.BorrowBookName, b.BorrowBookPublish
FROM Student s
FULL OUTER JOIN BorrowBook b ON s.StudentID = b.StudentID;
| StudentName | StudentAge | BorrowBookName | BorrowBookPublish |
|---|---|---|---|
| NULL | NULL | C語言程序設計 | 高等教育出版社 |
| 張三 | 25 | 馬克思主義政治經濟學 | 電子工業出版社 |
| 李四 | 26 | 毛澤東思想概論 | 高等教育出版社 |
| 王五 | 27 | 鄧小平理論 | 人民郵電出版社 |
| 趙六 | 28 | 大學生思想道德修養 | 中國鐵道出版社 |
| 無名氏 | 27 | NULL | NULL |
語意:左右表全保留,匹配則合併,否則 NULL。等同於 LEFT JOIN UNION RIGHT JOIN。適用於「雙邊資料完整性稽核」。
SELECT s.StudentName, s.StudentAge, b.BorrowBookName, b.BorrowBookPublish
FROM Student s
CROSS JOIN BorrowBook b;
-- 等價於
SELECT s.StudentName, s.StudentAge, b.BorrowBookName, b.BorrowBookPublish
FROM Student s, BorrowBook b; -- 無 WHERE 條件
每位學生配對每本書,產生所有可能組合。極少直接用於業務查詢,常見於:
OPTION (FORCE ORDER) 強制順序僅限除錯,生產環境慎用。-- 正確:ON 只放關聯邏輯
SELECT * FROM Student s
LEFT JOIN BorrowBook b ON s.StudentID = b.StudentID
WHERE b.BorrowBookPublish = '高等教育出版社'; -- 篩選放 WHERE
-- 錯誤:篩選放 ON 會改變外連接語意(等同內連接)
SELECT * FROM Student s
LEFT JOIN BorrowBook b ON s.StudentID = b.StudentID
AND b.BorrowBookPublish = '高等教育出版社';
| 連接類型 | 關鍵字 | 保留左表 | 保留右表 | 典型用途 |
|---|---|---|---|---|
| 內連接 | INNER JOIN / JOIN | 否 | 否 | 主從關聯、明細查詢 |
| 左外連接 | LEFT [OUTER] JOIN | 是 | 否 | 主表全保留、可選明細 |
| 右外連接 | RIGHT [OUTER] JOIN | 否 | 是 | 同左連接,表順序互換 |
| 完整外連接 | FULL [OUTER] JOIN | 是 | 是 | 雙邊完整性比對、資料稽核 |
| 交叉連接 | CROSS JOIN | 全排列 | 全排列 | 測試資料、維度組合、極少業務 |