在正規化資料庫中,跨表查詢是常態。Join 操作決定了如何組合多張表的資料,理解 Inner Join(內連接)與 Outer Join(外連接)的語義差異,是撰寫正確且高效查詢的關鍵。
| 特性 | Inner Join | Left/Right Outer Join |
|---|---|---|
| 語義 | 排他性 - 僅回傳符合條件的配對列 | 包容性 - 保留主表所有列,次表無配對則填 NULL |
| 結果筆數 | ≤ 兩表較小筆數 | ≥ 主表筆數 |
| 典型用途 | 主外鍵關聯、維度查詢 | 報表顯示所有主記錄、找出孤兒資料 |
-- 僅顯示有供應商的產品
SELECT ProductId, ProductName, Suppliers.SupplierId, CompanyName
FROM Products
INNER JOIN Suppliers ON Products.SupplierId = Suppliers.SupplierId
若 Products 中有 SupplierId = 50 但 Suppliers 無此記錄,該產品不會出現。
-- 顯示所有產品,無供應商者 CompanyName 為 NULL
SELECT ProductId, ProductName, Suppliers.SupplierId, CompanyName
FROM Products
LEFT OUTER JOIN Suppliers ON Products.SupplierId = Suppliers.SupplierId
-- 顯示所有供應商,無產品者 ProductName 為 NULL
SELECT ProductId, ProductName, Suppliers.SupplierId, CompanyName
FROM Products
RIGHT OUTER JOIN Suppliers ON Products.SupplierId = Suppliers.SupplierId
-- 1. 移除外鍵約束(僅為示範)
EXEC sp_helpconstraint Products
ALTER TABLE Products DROP CONSTRAINT FK_Products_Suppliers
-- 2. 插入無對應供應商的產品
INSERT INTO Products (ProductName, SupplierId, CategoryId)
VALUES ('Test Product', 50, 1)
-- 3. 執行 Left Join 驗證
SELECT ProductId, ProductName, Suppliers.SupplierId, CompanyName
FROM Products
LEFT OUTER JOIN Suppliers ON Products.SupplierId = Suppliers.SupplierId
WHERE Products.ProductName = 'Test Product'
保留兩張表所有列,無配對處填 NULL。SQL Server 7.0+ 支援。
SELECT * FROM TableA
FULL OUTER JOIN TableB ON TableA.Id = TableB.Id
無 ON 條件,產生兩表列數乘積。慎用!
SELECT * FROM Colors CROSS JOIN Sizes
同一張表扮演不同角色,如員工-主管關係。
SELECT E.Name AS Employee, M.Name AS Manager
FROM Employees E
LEFT JOIN Employees M ON E.ReportsTo = M.EmployeeId
UPDATE STATISTICS 讓優化器選擇最佳 Join 順序口訣:Inner 找共同,Left 保左邊,Right 保右邊,Full 都要。