T SQL查詢高階 詳解公用表表示式 CTE

2021-06-16 13:48:29 字數 2161 閱讀 1044

對於select查詢語句來說,通常情況下,為了使t-sql**更加簡潔和可讀,在乙個查詢中引用另外的結果集都是通過檢視而不是子查詢來進行分解的.但是,檢視是作為系統物件存在資料庫中,那對於結果集僅僅需要在儲存過程或是使用者自定義函式中使用一次的時候,使用檢視就顯得有些奢侈了.

公用表表示式(common table expression)是sql server 2005版本之後引入的乙個特性.cte可以看作是乙個臨時的結果集,可以在接下來的乙個select,insert,update,delete,merge語句中被多次引用。使用公用表示式可以讓語句更加清晰簡練.

除此之外,根據微軟對cte好處的描述,可以歸結為四點:

公用表示式的定義非常簡單,只包含三部分:

公用表表示式的名字(在with之後)

所涉及的列名(可選)

乙個select語句(緊跟as之後)

在msdn中的原型:

with expression_name [ ( column_name [,...n] ) ] 

as ( cte_query_definition )

按照是否遞迴,可以將公用表(cte)表示式分為遞迴公用表表示式和非遞迴公用表表示式.

非遞迴公用表表示式(cte)是查詢結果僅僅一次性返回乙個結果集用於外部查詢呼叫。並不在其定義的語句中呼叫其自身的cte

非遞迴公用表表示式(cte)的使用方式和檢視以及子查詢一致

比如乙個簡單的非遞迴公用表表示式:

當然,公用表表示式的好處之一是可以在接下來一條語句中多次引用:

前面我一直強調「在接下來的一條語句中」,意味著只能接下來一條使用:

由於cte只能在接下來一條語句中使用,因此,當需要接下來的一條語句中引用多個cte時,可以定義多個,中間用逗號分隔:

遞迴公用表表示式很像派生表(derived tables ),指的是在cte內的語句中呼叫其自身的cte.與派生表不同的是,cte可以在一次定義多次進行派生遞迴.對於遞迴的概念,是指乙個函式或是過程直接或者間接的呼叫其自身,遞迴的簡單概念圖如下:

遞迴在c語言中實現的乙個典型例子是斐波那契數列:

long fib(int n)   

上面c語言**可以看到,要構成遞迴函式,需要兩部分。第一部分是基礎部分,返回固定值,也就是告訴程式何時開始遞迴。第二部分是迴圈部分,是函式或過程直接或者間接呼叫自身進行遞迴.

對於遞迴公用表示式來說,實現原理也是相同的,同樣需要在語句中定義兩部分:

在sql這兩部分通過union all連線結果集進行返回:

比如:在adventurework中,我想知道每個員工所處的層級,0是最高端

這麼複雜的查詢通過遞迴cte變得如此優雅和簡潔.這也是cte最強大的地方.

當然,越強大的力量,就需要被約束.如果使用不當的話,遞迴cte可能會出現無限遞迴。從而大量消耗sql server的伺服器資源.因此,sql server提供了option選項,可以設定最大的遞迴次數:

還是上面那個語句,限制了遞迴次數:

所提示的訊息:

cte是一種十分優雅的存在。cte所帶來最大的好處是**可讀性的提公升,這是良好**的必須品質之一。使用遞迴cte可以更加輕鬆愉快的用優雅簡潔的方式實現複雜的查詢。

T SQL查詢高階 詳解公用表表示式 CTE

對於select查詢語句來說,通常情況下,為了使t sql 更加簡潔和可讀,在乙個查詢中引用另外的結果集都是通過檢視而不是子查詢來進行分解的.但是,檢視是作為系統物件存在資料庫中,那對於結果集僅僅需要在儲存過程或是使用者自定義函式中使用一次的時候,使用檢視就顯得有些奢侈了.公用表表示式 common...

T SQL查詢高階 詳解公用表表示式 CTE

對於select查詢語句來說,通常情況下,為了使t sql 更加簡潔和可讀,在乙個查詢中引用另外的結果集都是通過檢視而不是子查詢來進行分解的.但是,檢視是作為系統物件存在資料庫中,那對於結果集僅僅需要在儲存過程或是使用者自定義函式中使用一次的時候,使用檢視就顯得有些奢侈了.公用表表示式 common...

T SQL查詢高階 詳解公用表表示式 CTE

對於select查詢語句來說,通常情況下,為了使t sql 更加簡潔和可讀,在乙個查詢中引用另外的結果集都是通過檢視而不是子查詢來進行分解的.但是,檢視是作為系統物件存在資料庫中,那對於結果集僅僅需要在儲存過程或是使用者自定義函式中使用一次的時候,使用檢視就顯得有些奢侈了.公用表表示式 common...