日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁(yè) > > 充電吧
[導(dǎo)讀]在TSQL腳本中,也能實(shí)現(xiàn)遞歸查詢(xún),SQL Server提供CTE(Common?Table?Expression),只需要編寫(xiě)少量的代碼,就能實(shí)現(xiàn)遞歸查詢(xún),本文詳細(xì)介紹CTE遞歸調(diào)用的特性和使用示例



在TSQL腳本中,也能實(shí)現(xiàn)遞歸查詢(xún),SQL Server提供CTE(Common?Table?Expression),只需要編寫(xiě)少量的代碼,就能實(shí)現(xiàn)遞歸查詢(xún),本文詳細(xì)介紹CTE遞歸調(diào)用的特性和使用示例,遞歸查詢(xún)主要用于層次結(jié)構(gòu)的查詢(xún),從葉級(jí)(Leaf Level)向頂層(Root Level)查詢(xún),或從頂層向葉級(jí)查詢(xún),或遞歸的路徑(Path)。

一,遞歸查詢(xún)?cè)?/p>

CTE的遞歸查詢(xún)必須滿(mǎn)足三個(gè)條件:初始條件,遞歸調(diào)用表達(dá)式,終止條件,CTE 遞歸查詢(xún)的偽代碼如下:

WITH?cte_name?(?column_name?[,...n]?)
AS
(
--Anchor?member?is?defined
CTE_query_definition?
UNION?ALL
--Recursive?member?is?defined?referencing?cte_name
CTE_query_definition?
)
--?Statement?using?the?CTE
SELECT?*
FROM?cte_name

1,遞歸查詢(xún)至少包含兩個(gè)子查詢(xún):

第一個(gè)子查詢(xún)稱(chēng)作定點(diǎn)(Anchor)子查詢(xún):定點(diǎn)查詢(xún)只是一個(gè)返回有效表的查詢(xún),用于設(shè)置遞歸的初始值;第二個(gè)子查詢(xún)稱(chēng)作遞歸子查詢(xún):該子查詢(xún)調(diào)用CTE名稱(chēng),觸發(fā)遞歸查詢(xún),實(shí)際上是遞歸子查詢(xún)調(diào)用遞歸子查詢(xún);兩個(gè)子查詢(xún)使用union all,求并集;

2,CTE的遞歸終止條件

遞歸查詢(xún)沒(méi)有顯式的遞歸終止條件,只有當(dāng)遞歸子查詢(xún)返回空結(jié)果集(沒(méi)有數(shù)據(jù)行返回)或是超出了遞歸次數(shù)的最大限制時(shí),才停止遞歸。

默認(rèn)的遞歸查詢(xún)次數(shù)是100,可以使用查詢(xún)提示(hint):MAXRECURSION 控制遞歸的最大次數(shù):OPTION( MAXRECURSION 16);如果允許無(wú)限制的遞歸次數(shù),使用查詢(xún)提示:option(maxrecursion 0);當(dāng)遞歸查詢(xún)達(dá)到指定或默認(rèn)的 MAXRECURSION 數(shù)量限制時(shí),SQL Server將結(jié)束查詢(xún)并返回錯(cuò)誤,如下:

The statement terminated. The maximum recursion 10 has been exhausted before statement completion.

事務(wù)執(zhí)行失敗,該事務(wù)包含的所有操作都被回滾。在產(chǎn)品環(huán)境中,慎用maxrecursion 查詢(xún)提示,推薦通過(guò) where 條件限制遞歸的次數(shù)。

3,遞歸步驟

step1:定點(diǎn)子查詢(xún)?cè)O(shè)置CTE的初始值,即CTE的初始值Set0;

遞歸調(diào)用的子查詢(xún)過(guò)程:遞歸子查詢(xún)調(diào)用遞歸子查詢(xún);

step2:遞歸子查詢(xún)第一次調(diào)用CTE名稱(chēng),CTE名稱(chēng)是指CTE的初始值Set0,第一次執(zhí)行遞歸子查詢(xún)之后,CTE名稱(chēng)是指結(jié)果集Set1;

step3:遞歸子查詢(xún)第二次調(diào)用CTE名稱(chēng),CTE名稱(chēng)是指Set1,第二次執(zhí)行遞歸子查詢(xún)之后,CTE名稱(chēng)是指結(jié)果集Set2;

step4:在第N次執(zhí)行遞歸子查詢(xún)時(shí),CTE名稱(chēng)是指Set(N-1),遞歸子查詢(xún)都引用前一個(gè)遞歸子查詢(xún)的結(jié)果集;

Step5:如果遞歸子查詢(xún)返回空數(shù)據(jù)行,或超出遞歸次數(shù)的最大限制,停止遞歸;

二,遞歸查詢(xún)示例(員工職稱(chēng))

1,創(chuàng)建測(cè)試數(shù)據(jù)

ManagerID是UserID的父節(jié)點(diǎn),這是一個(gè)非常簡(jiǎn)單的層次結(jié)構(gòu)模型。

use?tempdb
go?

create?table?dbo.dt_user
(
????UserID?int,
????ManagerID?int,
????Name?Nvarchar(10)
)

insert?into?dbo.dt_user
select?1,-1,N'Boss'
union?all
select?11,1,N'A1'
union?all
select?12,1,N'A2'
union?all
select?13,1,N'A3'
union?all
select?111,11,N'B1'
union?all
select?112,11,N'B2'
union?all
select?121,12,N'C1'

2,查詢(xún)每個(gè)User的的直接上級(jí)Manager

;with?cte?as
(
select?UserID,ManagerID,name,name?as?ManagerName
from?dbo.dt_user
where?ManagerID=-1

union?all
select?c.UserID,c.ManagerID,c.Name,p.name?as?ManagerName
from?cte?P
inner?join?dbo.dt_user?c
????on?p.UserID=c.ManagerID
)
select?UserID,ManagerID,Name,ManagerName
from?cte
order?by?UserID

step1:查詢(xún)ManagerID=-1,作為root node,這是遞歸查詢(xún)的起始點(diǎn)。

step2:迭代公式是 union all 下面的查詢(xún)語(yǔ)句。在查詢(xún)語(yǔ)句中調(diào)用中cte,而查詢(xún)語(yǔ)句就是cte的組成部分,即 “自己調(diào)用自己”,這就是遞歸的真諦所在。

所謂迭代,是指每一次遞歸都要調(diào)用上一次查詢(xún)的結(jié)果集,Union ALL是指每次都把結(jié)果集并在一起。

step3-N,迭代公式利用上一次查詢(xún)返回的結(jié)果集執(zhí)行特定的查詢(xún),直到CTE返回null 或達(dá)到最大的迭代次數(shù),默認(rèn)值是32。最終的結(jié)果集是迭代公式返回的各個(gè)結(jié)果集的并集,求并集是由Union All 子句定義的,并且只能使用Union ALL。

3,查詢(xún)路徑,在層次結(jié)構(gòu)中查詢(xún)子節(jié)點(diǎn)到父節(jié)點(diǎn)的path

;with?cte?as
(
select?UserID,ManagerID,name,cast(name?as?nvarchar(max))?as?ReportPath
from?dbo.dt_user
where?ManagerID=-1

union?all
select?c.UserID,c.ManagerID,c.Name,c.name+'->'+p.ReportPath?as?ReportPath
from?cte?P
inner?join?dbo.dt_user?c
????on?p.UserID=c.ManagerID
)
select?UserID,ManagerID,Name,ReportPath
from?cte
order?by?UserID

查詢(xún)結(jié)果如下截圖:

三,遞歸查詢(xún)示例(行政區(qū)劃)

1,需求模擬

在TSQL中實(shí)現(xiàn)層次結(jié)構(gòu),例如有這樣一種數(shù)據(jù)結(jié)構(gòu),省,市,縣,鄉(xiāng),村,如何使用一張表表示這種數(shù)據(jù)結(jié)構(gòu),并且允許是不對(duì)稱(chēng)的,例如,上海市是個(gè)直轄市,沒(méi)有省份。

create?table?dbo.hierarchy
(
ID??int?not?null?primary?key,
--type?int?not?null,
ParentID?int?not?null,
name?varchar(100)?not?null
)

type表示類(lèi)型,可以設(shè)置:省,Type是1;市,type是2,以此類(lèi)推。

ParentID標(biāo)識(shí)的是父級(jí)ID,例如信陽(yáng)市的ParentID是河南省的ID。

2,插入測(cè)試數(shù)據(jù)

測(cè)試數(shù)據(jù)格式說(shuō)明了歸屬關(guān)系,博主懶,去掉type字段。

insert?into?dbo.hierarchy
values(1,0,'河南省')
,(2,1,'信陽(yáng)市'),(3,2,'淮濱縣'),(4,3,'蘆集鄉(xiāng)'),(12,3,'鄧灣鄉(xiāng)'),(13,3,'臺(tái)頭鄉(xiāng)'),(14,3,'谷堆鄉(xiāng)')
??????????????,(8,2,'固始縣'),(9,8,'李店鄉(xiāng)')
??????????????,(10,2,'息縣'),(11,10,'關(guān)店鄉(xiāng)')
,(5,1,'安陽(yáng)市'),(6,5,'滑縣'),(7,6,'老廟鄉(xiāng)')
,(15,1,'南陽(yáng)市'),(16,15,'方城縣')
,(17,1,'駐馬店市'),(18,17,'正陽(yáng)縣')


select?*?
from?dbo.hierarchy?
order?by?ParentID

3,實(shí)現(xiàn)由父級(jí)向子級(jí)的查詢(xún)

由于實(shí)際的數(shù)據(jù)可能有很多,所以,要想獲取河南省下的所有市,縣,鄉(xiāng),村等信息,必須使用遞歸查詢(xún)

;with?cte(Id,ParentID,Name)?as
(
select?*?
from?dbo.hierarchy?
where?id=1

union?all
select?h.*?
from?dbo.hierarchy?h
inner?join?cte?c?on?h.ParentID=c.id?
--where?c.id!=h.ID
)
select?*
from?cte
order?by?ParentID

如果要查看向內(nèi)遞歸到多少level,可以使用派生列,level=0是省level,level=1是市l(wèi)evel,依次類(lèi)推。

;with?cte(Id,ParentID,Name,Level)?as
(
select?ID,ParentID,Name,0?as?Level
from?dbo.hierarchy?
where?id=1

union?all
select?h.ID,h.ParentID,h.Name,c.Level+1?as?Level
from?dbo.hierarchy?h
inner?join?cte?c?on?h.ParentID=c.id?
--where?c.id!=h.ID
)
select?*
from?cte
order?by?ParentID

查詢(xún)結(jié)果如圖:

4,由子級(jí)向父級(jí)的遞歸查詢(xún)

;with?cte?as
(
select?ID,ParentID,name
from?dbo.hierarchy
where?id=4?--蘆集鄉(xiāng)的ID

union?all
select?h.ID,h.ParentID,h.name
from?dbo.hierarchy?h
inner?join?cte?c?on?h.id=c.ParentID
)
select?ID,ParentID,name
from?cte
order?by?ParentID

查詢(xún)結(jié)果如圖:

?

參考文檔:

Recursive Queries Using Common Table Expressions

WITH common_table_expression (Transact-SQL)


本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專(zhuān)欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動(dòng)電源

在工業(yè)自動(dòng)化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動(dòng)力設(shè)備,其驅(qū)動(dòng)電源的性能直接關(guān)系到整個(gè)系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動(dòng)勢(shì)抑制與過(guò)流保護(hù)是驅(qū)動(dòng)電源設(shè)計(jì)中至關(guān)重要的兩個(gè)環(huán)節(jié),集成化方案的設(shè)計(jì)成為提升電機(jī)驅(qū)動(dòng)性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動(dòng)電源

LED 驅(qū)動(dòng)電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個(gè)照明設(shè)備的使用壽命。然而,在實(shí)際應(yīng)用中,LED 驅(qū)動(dòng)電源易損壞的問(wèn)題卻十分常見(jiàn),不僅增加了維護(hù)成本,還影響了用戶(hù)體驗(yàn)。要解決這一問(wèn)題,需從設(shè)計(jì)、生...

關(guān)鍵字: 驅(qū)動(dòng)電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動(dòng)電源的公式,電感內(nèi)電流波動(dòng)大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計(jì) 驅(qū)動(dòng)電源

電動(dòng)汽車(chē)(EV)作為新能源汽車(chē)的重要代表,正逐漸成為全球汽車(chē)產(chǎn)業(yè)的重要發(fā)展方向。電動(dòng)汽車(chē)的核心技術(shù)之一是電機(jī)驅(qū)動(dòng)控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動(dòng)系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動(dòng)汽車(chē)的動(dòng)力性能和...

關(guān)鍵字: 電動(dòng)汽車(chē) 新能源 驅(qū)動(dòng)電源

在現(xiàn)代城市建設(shè)中,街道及停車(chē)場(chǎng)照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨(dú)特的優(yōu)勢(shì)逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動(dòng)電源 LED

LED通用照明設(shè)計(jì)工程師會(huì)遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動(dòng)電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動(dòng)電源的電磁干擾(EMI)問(wèn)題成為了一個(gè)不可忽視的挑戰(zhàn)。電磁干擾不僅會(huì)影響LED燈具的正常工作,還可能對(duì)周?chē)娮釉O(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來(lái)解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動(dòng)電源

開(kāi)關(guān)電源具有效率高的特性,而且開(kāi)關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動(dòng)電源

關(guān)鍵字: LED 驅(qū)動(dòng)電源 開(kāi)關(guān)電源

LED驅(qū)動(dòng)電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動(dòng)LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動(dòng)電源
關(guān)閉