這是 sql server 幫助文檔關(guān)于apply的描述:
使用 APPLY 運(yùn)算符(2005或以上版本)可以為實(shí)現(xiàn)查詢操作的外部表表達(dá)式返回的每個(gè)行調(diào)用表值函數(shù)。表值函數(shù)作為右輸入,外部表表達(dá)式作為左輸入。通過(guò)對(duì)右輸入求值來(lái)獲得左輸入每一行的計(jì)算結(jié)果,生成的行被組合起來(lái)作為最終輸出。APPLY 運(yùn)算符生成的列的列表是左輸入中的列集,后跟右輸入返回的列的列表。
APPLY 有兩種形式: CROSS APPLY 和 OUTER APPLY。CROSS APPLY 僅返回外部表中通過(guò)表值函數(shù)生成結(jié)果集的行。OUTER APPLY 既返回生成結(jié)果集的行,也返回不生成結(jié)果集的行,其中表值函數(shù)生成的列中的值為 NULL。
看一下例子:
select * from table1 join MyFunction(1) on 1=1
MyFunction 的參數(shù)是一個(gè)常量,可以返回一個(gè)表。
但有時(shí)候我們希望以 table1 的字段作為參數(shù),傳進(jìn)函數(shù)去計(jì)算,像:
select * from table1 join MyFunction(id) on 1=1
這樣是會(huì)出錯(cuò)的。這個(gè)時(shí)候我們就可以用 apply 來(lái)實(shí)現(xiàn)了。例如:
select * from table1 cross apply MyFunction(id) on 1=1
簡(jiǎn)單的說(shuō),apply 允許我們將前面結(jié)果集每一行的數(shù)據(jù)作為參數(shù),傳遞到后面的表達(dá)式,后面的表達(dá)式可以是一個(gè)表值函數(shù),或者select結(jié)果集。
實(shí)際項(xiàng)目應(yīng)用:
產(chǎn)品表和點(diǎn)擊率統(tǒng)計(jì)表,按產(chǎn)品最近一個(gè)月點(diǎn)擊率排序。
如果不用apply,實(shí)現(xiàn)起來(lái)就比較麻煩,用 apply 實(shí)現(xiàn)起來(lái)大概就是這樣的:
;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 的區(qū)別就好像left join 與 join 的區(qū)別。如果 apply 不生成行,outer apply 也會(huì)返回該行,而 cross apply 則不會(huì)輸出該行。
so,當(dāng)你在需要將某個(gè)字段的值作為參數(shù)使用時(shí),或者用join實(shí)現(xiàn)起來(lái)比較復(fù)雜時(shí),就可以考慮apply來(lái)實(shí)現(xiàn)。
新聞熱點(diǎn)
疑難解答
圖片精選