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

SQL Server CROSS APPLY 與 OUTER APPLY 深度解析:語法、差異、效能與 LEFT JOIN 對比

     編輯:關於SqlServer

APPLY 運算子核心概念

APPLY 允許將右側表值函數/子查詢套用至左側表的每一行,邏輯處理順序固定為先左後右(異於 JOIN 可交換順序)。這使得右側運算式可引用左側欄位,解決 JOIN 無法處理的「每行動態計算」場景。

兩種形式語義差異

運算子行為相當於
CROSS APPLY僅返回右側有結果的左側行INNER JOIN(但右側可引用左側欄位)
OUTER APPLY返回所有左側行,右側無結果填 NULLLEFT JOIN(但右側可引用左側欄位)

實戰範例:分類與明細表

測試資料:


-- Category: Id, Name
-- CategoryDetail: Id, CategoryId, Cry
INSERT Category VALUES (1,'Cat'), (2,'Dog'), (3,'Tiger');
INSERT CategoryDetail VALUES (1,1,'喵'), (2,2,'汪');
-- Tiger (Id=3) 無對應明細

OUTER APPLY 結果(含 Tiger)


SELECT * FROM dbo.Category a 
OUTER APPLY (SELECT * FROM dbo.CategoryDetail b WHERE b.CategoryId = a.Id) AS c;

OUTER APPLY 結果

Tiger 行保留,右側欄位為 NULL。

CROSS APPLY 結果(排除 Tiger)


SELECT * FROM dbo.Category a 
CROSS APPLY (SELECT * FROM dbo.CategoryDetail b WHERE b.CategoryId = a.Id) AS c;

CROSS APPLY 結果

僅返回 Cat、Dog 兩行。

OUTER APPLY vs LEFT JOIN:語義相同但能力不同


-- LEFT JOIN 寫法
SELECT * FROM dbo.Category a 
LEFT JOIN dbo.CategoryDetail b ON b.CategoryId = a.Id;

LEFT JOIN 結果

結果與 OUTER APPLY 相同。

核心差異對比

維度OUTER APPLYLEFT JOIN
右側運算式任意複雜子查詢、表值函數、預存程序僅限資料表/檢視表
引用左側欄位原生支援需移至 WHERE/ON 子句,受限
效能較慢(逐行執行右側邏輯)較快(集合式運算,優化器支援完善)
可讀性複雜邏輯集中封裝標準 SQL,廣為人知

效能實測結論

LEFT JOIN 效能優於 OUTER APPLY。優化器對 JOIN 有成熟的演算法選擇(Hash/Merge/Nested Loops),而 APPLY 多為 Nested Loops 逐行執行。建議:能用 LEFT JOIN 解決的場景優先用 JOIN,僅在需封裝複雜邏輯/呼叫函數時使用 APPLY。

適用版本限制

資料庫相容性層級需 ≥ 90(SQL Server 2005+)。

進階應用:搭配表值函數


CREATE FUNCTION fn_GetTopOrders(@CustomerId INT, @TopN INT)
RETURNS TABLE AS RETURN
  SELECT TOP (@TopN) * FROM Orders WHERE CustomerId = @CustomerId ORDER BY OrderDate DESC;

-- 每位客戶最新 3 筆訂單
SELECT c.*, o.* 
FROM Customers c 
CROSS APPLY fn_GetTopOrders(c.CustomerId, 3) o;

此場景無法用 JOIN 替代,展現 APPLY 獨特價值。

總結選型指南

  1. 標準表關聯 → LEFT/INNER JOIN
  2. 需呼叫表值函數/複雜子查詢且每行參數不同 → CROSS/OUTER APPLY
  3. 效能敏感場景 → 能用 JOIN 絕不用 APPLY
  4. 相容性層級 < 90 → 僅能用 JOIN
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved