详解公用表表达式(CTE)
簡(jiǎn)介
???? 對(duì)于SELECT查詢語(yǔ)句來(lái)說(shuō),通常情況下,為了使T-SQL代碼更加簡(jiǎn)潔和可讀,在一個(gè)查詢中引用另外的結(jié)果集都是通過(guò)視圖而不是子查詢來(lái)進(jìn)行分解的.但是,視圖是作為系統(tǒng)對(duì)象存在數(shù)據(jù)庫(kù)中,那對(duì)于結(jié)果集僅僅需要在存儲(chǔ)過(guò)程或是用戶自定義函數(shù)中使用一次的時(shí)候,使用視圖就顯得有些奢侈了.
??? 公用表表達(dá)式(Common Table Expression)是SQL SERVER 2005版本之后引入的一個(gè)特性.CTE可以看作是一個(gè)臨時(shí)的結(jié)果集,可以在接下來(lái)的一個(gè)SELECT,INSERT,UPDATE,DELETE,MERGE語(yǔ)句中被多次引用。使用公用表達(dá)式可以讓語(yǔ)句更加清晰簡(jiǎn)練.
???? 除此之外,根據(jù)微軟對(duì)CTE好處的描述,可以歸結(jié)為四點(diǎn):
- ???? 可以定義遞歸公用表表達(dá)式(CTE)
- ???? 當(dāng)不需要將結(jié)果集作為視圖被多個(gè)地方引用時(shí),CTE可以使其更加簡(jiǎn)潔
- ??? GROUP BY語(yǔ)句可以直接作用于子查詢所得的標(biāo)量列
- ??? 可以在一個(gè)語(yǔ)句中多次引用公用表表達(dá)式(CTE)
公用表表達(dá)式(CTE)的定義
??? 公用表達(dá)式的定義非常簡(jiǎn)單,只包含三部分:
??? 在MSDN中的原型:
WITH expression_name [ ( column_name [,...n] ) ] AS ( CTE_query_definition )?? 按照是否遞歸,可以將公用表(CTE)表達(dá)式分為遞歸公用表表達(dá)式和非遞歸公用表表達(dá)式.
非遞歸公用表表達(dá)式(CTE)
?? 非遞歸公用表表達(dá)式(CTE)是查詢結(jié)果僅僅一次性返回一個(gè)結(jié)果集用于外部查詢調(diào)用。并不在其定義的語(yǔ)句中調(diào)用其自身的CTE
?? 非遞歸公用表表達(dá)式(CTE)的使用方式和視圖以及子查詢一致
?? 比如一個(gè)簡(jiǎn)單的非遞歸公用表表達(dá)式:
??
?? 當(dāng)然,公用表表達(dá)式的好處之一是可以在接下來(lái)一條語(yǔ)句中多次引用:
??
?? 前面我一直強(qiáng)調(diào)“在接下來(lái)的一條語(yǔ)句中”,意味著只能接下來(lái)一條使用:
??
?? 由于CTE只能在接下來(lái)一條語(yǔ)句中使用,因此,當(dāng)需要接下來(lái)的一條語(yǔ)句中引用多個(gè)CTE時(shí),可以定義多個(gè),中間用逗號(hào)分隔:
??
遞歸公用表表達(dá)式(CTE)
??? 遞歸公用表表達(dá)式很像派生表(Derived Tables ),指的是在CTE內(nèi)的語(yǔ)句中調(diào)用其自身的CTE.與派生表不同的是,CTE可以在一次定義多次進(jìn)行派生遞歸.對(duì)于遞歸的概念,是指一個(gè)函數(shù)或是過(guò)程直接或者間接的調(diào)用其自身,遞歸的簡(jiǎn)單概念圖如下:
??
??? 遞歸在C語(yǔ)言中實(shí)現(xiàn)的一個(gè)典型例子是斐波那契數(shù)列:
long fib(int n) { if (n==0) return 0;if (n==1) return 1; if (n>1) return fib(n-1)+fib(n-2); }?? 上面C語(yǔ)言代碼可以看到,要構(gòu)成遞歸函數(shù),需要兩部分。第一部分是基礎(chǔ)部分,返回固定值,也就是告訴程序何時(shí)開始遞歸。第二部分是循環(huán)部分,是函數(shù)或過(guò)程直接或者間接調(diào)用自身進(jìn)行遞歸.
?? 對(duì)于遞歸公用表達(dá)式來(lái)說(shuō),實(shí)現(xiàn)原理也是相同的,同樣需要在語(yǔ)句中定義兩部分:
- ?? 基本語(yǔ)句
- ?? 遞歸語(yǔ)句
?? 在SQL這兩部分通過(guò)UNION ALL連接結(jié)果集進(jìn)行返回:
?? 比如:在AdventureWork中,我想知道每個(gè)員工所處的層級(jí),0是最高級(jí)
??
?? 這么復(fù)雜的查詢通過(guò)遞歸CTE變得如此優(yōu)雅和簡(jiǎn)潔.這也是CTE最強(qiáng)大的地方.
?? 當(dāng)然,越強(qiáng)大的力量,就需要被約束.如果使用不當(dāng)?shù)脑?#xff0c;遞歸CTE可能會(huì)出現(xiàn)無(wú)限遞歸。從而大量消耗SQL Server的服務(wù)器資源.因此,SQL Server提供了OPTION選項(xiàng),可以設(shè)定最大的遞歸次數(shù):
?? 還是上面那個(gè)語(yǔ)句,限制了遞歸次數(shù):
??
?? 所提示的消息:
??
?? 這個(gè)最大遞歸次數(shù)往往是根據(jù)數(shù)據(jù)所代表的具體業(yè)務(wù)相關(guān)的,比如這里,假設(shè)公司層級(jí)最多只有2層.
總結(jié)?
??? CTE是一種十分優(yōu)雅的存在。CTE所帶來(lái)最大的好處是代碼可讀性的提升,這是良好代碼的必須品質(zhì)之一。使用遞歸CTE可以更加輕松愉快的用優(yōu)雅簡(jiǎn)潔的方式實(shí)現(xiàn)復(fù)雜的查詢。
與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的详解公用表表达式(CTE)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 直线折旧与加速折旧的区别(直线折旧法和加
- 下一篇: 10分钟理解游标