SQL Server with as(CTE)

with as短語,也叫做子查詢部分(subquery factoring)。
如果with as所定義的表名被調用兩次以上,則優化器會自動將with as短語所獲取的數據存入一個TEMP表裏。如果只被調用一次,則不會。
而提示materrialize則是強制將with as短語獲取的數據存入一個全局臨時表裏。很多查詢通過這種方式可以提高速度。

CTE語法如下:
[ WITH <common_table_expression> [ ,n ] ] 
<common_table_expression>::= 
        expression_name [ ( column_name [ ,n ] ) ] 
    AS 
        ( CTE_query_definition ) 

使用CTE需要注意:
1、CTE後面必須直接跟使用CTE的SQL語句,否則,CTE將失效。
2、CTE後面也可以跟其它的CTE,但只能使用一個with,多個CTE之間使用逗號(,)分隔。

with
p1 as(
    select * from dbo.Person where LastName like '%a%'
),
p2 as(
    select * from dbo.Person where Address like '%e%'
)
select a.* from p1 a join p2 b on a.PID=b.PID

3、如果CTE的表達式名稱與某個數據表或視圖重名,則緊跟在該CTE後面的SQL語句使用的仍然是CTE,當然,後面的SQL語句使用的就是數據表或視圖了。

4、CTE遞歸調用:

--if(exists(select * from sys.tables where name='t_tree'))
--drop table t_tree
--go
--create table t_tree(
--    id int not null,
--    node_name varchar(50) null,
--    parent_id int not null
--)
--go

--insert into dbo.t_tree(id,node_name,parent_id)
--values(1,'廣東省',0),(2,'廣州市',1),(3,'惠州市',1),(4,'白雲區',2),(5,'天河區',2),(6,'越秀區',2),(7,'黃埔區',2),(8,'龍門縣',3)

select * from dbo.t_tree
--使用CTE遞歸查詢某省下所有區域--使用 MAXRECURSION 來防止不合理的遞歸
;with district(id,node_name,parent_id,level) as(
    select *,0 as level from dbo.t_tree where node_name='廣東省' --定點子查詢
    union all
    select a.*,b.level+1 from dbo.t_tree a join district b
    on a.parent_id=b.id--遞歸子查詢
)
select * from district
option(maxrecursion 5)---- 限制特定語句所允許的遞歸級數,以防止出現無限循環

CTE遞歸查詢終止條件:
遞歸查詢沒有顯式的終止條件,只有當遞歸子查詢返回的是空結果集(沒有數據行返回),或是超出遞歸次數最大限制時,才停止遞歸。
默認的遞歸查詢次數是100.可用option(maxrecursion N)來控制遞歸最大次數。 

參數文獻:

https://blog.csdn.net/johnf_nash/article/details/78681060

https://www.21ic.com/tougao/article/5656.html#


 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章