這是 sql server 幫助文檔關於apply的描述:
使用 APPLY 運算符(2005或以上版本)可以為實現查詢操作的外部表表達式返回的每個行調用表值函數。表值函數作為右輸入,外部表表達式作為左輸入。通過對右輸入求值來獲得左輸入每一行的計算結果,生成的行被組合起來作為最終輸出。APPLY 運算符生成的列的列表是左輸入中的列集,后跟右輸入返回的列的列表。
APPLY 有兩種形式: CROSS APPLY 和 OUTER APPLY。CROSS APPLY 僅返回外部表中通過表值函數生成結果集的行。OUTER APPLY 既返回生成結果集的行,也返回不生成結果集的行,其中表值函數生成的列中的值為 NULL。
看一下例子:
select * from table1 join MyFunction(1) on 1=1
MyFunction 的參數是一個常量,可以返回一個表。
但有時候我們希望以 table1 的字段作為參數,傳進函數去計算,像:
select * from table1 join MyFunction(id) on 1=1
這樣是會出錯的。這個時候我們就可以用 apply 來實現了。例如:
select * from table1 cross apply MyFunction(id) on 1=1
簡單的說,apply 允許我們將前面結果集每一行的數據作為參數,傳遞到后面的表達式,后面的表達式可以是一個表值函數,或者select結果集。
實際項目應用:
產品表和點擊率統計表,按產品最近一個月點擊率排序。
如果不用apply,實現起來就比較麻煩,用 apply 實現起來大概就是這樣的:
;with cteResult as( select row_number() over(order by HitCount) as rowid, ProductID, ProductName from ProductInfo pi with(nolock) outer apply(select sum(HitCount) HitCount from HitStatisticsInfo hsi where hsi.TargetID = pi.ProductID and hsi.HitTime >= '2015-08-08' group by TargetID) hsi where pi.IsDel = 0) select * from cteResult where rowid between 1 and 20
至於 cross apply 與 outer apply 的區別就好像left join 與 join 的區別。如果 apply 不生成行,outer apply 也會返回該行,而 cross apply 則不會輸出該行。
so,當你在需要將某個字段的值作為參數使用時,或者用join實現起來比較復雜時,就可以考慮apply來實現。