新聞中心
以下的文章主要向大家講述的是SQL Server CTEs 的遞歸功能是SQL Server數(shù)據(jù)庫(kù)中的三種保存臨時(shí)結(jié)果的實(shí)際操作方法之一。其另兩種是臨時(shí)表與View,當(dāng)然你也可以說(shuō)View并不保存數(shù)據(jù),從這一點(diǎn)上來(lái)將, CTE更像View一些。

創(chuàng)新互聯(lián)專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于做網(wǎng)站、成都網(wǎng)站設(shè)計(jì)、三原網(wǎng)絡(luò)推廣、微信小程序定制開發(fā)、三原網(wǎng)絡(luò)營(yíng)銷、三原企業(yè)策劃、三原品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營(yíng)等,從售前售中售后,我們都將竭誠(chéng)為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);創(chuàng)新互聯(lián)為所有大學(xué)生創(chuàng)業(yè)者提供三原建站搭建服務(wù),24小時(shí)服務(wù)熱線:18980820575,官方網(wǎng)址:www.cdcxhl.com
當(dāng)你的查詢需要從一個(gè)源表中統(tǒng)計(jì)出結(jié)果,基于這個(gè)結(jié)果再做進(jìn)一步的統(tǒng)計(jì),如此3次以上的話,你必然會(huì)用到View或者臨時(shí)表,現(xiàn)在你也可以考慮用CTE了。
CTE的語(yǔ)法相當(dāng)?shù)暮?jiǎn)單, 如下:
With CTE的名字 AS
(
子查詢
)
Select * from CTE的名字
SQL Server CTEs支持在定義時(shí)引用自身,從而可以達(dá)到遞歸的目的,看下面的例子(1):
- ---prepare test data
- SET NOCOUNT ON;
- CREATE TABLE dbo.Parts
- (
- partid INT NOT NULL PRIMARY KEY,
- partname VARCHAR(25) NOT NULL
- );
- INSERT INTO dbo.Parts(partid, partname)
- select 1, 'Black Tea'
- union all select 2, 'White Tea'
- union all select 3, 'Latte'
- union all select 4, 'Espresso'
- CREATE TABLE dbo.BOM
- (
- partid INT NOT NULL REFERENCES dbo.Parts,
- assemblyid INT NULL REFERENCES dbo.Parts,
- unit VARCHAR(3) NOT NULL,
- qty DECIMAL(8, 2) NOT NULL,
- UNIQUE(partid, assemblyid),
- CHECK (partid <> assemblyid)
- );
- INSERT INTO dbo.BOM(partid, assemblyid, unit, qty)
- select 1, NULL, 'EA', 1.00
- union all
- select 2, 1, 'EA', 1.00
- union all
- select 3, 2, 'EA', 1.00
- union all
- select 4, 3, 'EA', 1.00
- -- perform the test
- WITH BOMTC AS(
- SELECT assemblyid, partid
- FROM dbo.BOM
- WHERE assemblyid IS NOT NULL
- UNION ALL
- SELECT P.assemblyid, C.partid
- FROM BOMTC AS P
- JOIN dbo.BOM AS C ON C.assemblyid = P.partid
- )
- SELECT DISTINCT assemblyid, partid FROM BOMTC;
輸出結(jié)果如下:
例子(2):
- create table Employee
- (
- MgrId int,
- EmpId int,
- Title nvarchar(256)
- )
- insert into employee
- select NULL, 1 ,'CEO'
- union all
- select 1, 2, 'VP'
- union all
- select 2, 3, 'Dev Manager'
- union all
- select 2, 4, 'QA Manager'
- union all
- select 1, 5, 'Sales Manager'
- union all
- select 3, 30, 'Developer'
- union all
- select 3, 31, 'Developer'
- union all
- select 4, 40, 'Tester'
- union all
- select 4, 41, 'Tester'
- With DirectReports as
- (
- select MgrId, EmpId, Title, 0 as [Level] from Employee where MgrId is null
- union all
- select a.MgrId, a.EmpId, a.Title, [Level]+1 as [Level]
- from Employee a join DirectReports b on a.MgrId=b.EmpId
- )
- select * from DirectReports
結(jié)果:
講解:重點(diǎn)是子查詢中的兩個(gè)select語(yǔ)句,以上述例子加以說(shuō)明:
***個(gè)Select子句被稱為錨點(diǎn)語(yǔ)句,它返回的結(jié)果跟普通的SQL沒(méi)有區(qū)別,在這里返回MgrID為null的員工。
第二個(gè)子句就沒(méi)那么普通了,它被稱為遞歸語(yǔ)句,請(qǐng)注重到在from后面, Employee和DirectReport進(jìn)行了鏈接操作。你一定會(huì)問(wèn),DirectReport的定義還沒(méi)完成,這個(gè)名字代表什么結(jié)果呢?答案是它不只是代表了一個(gè)結(jié)果,實(shí)際上代表了一系列的結(jié)果。換句話說(shuō),在DirectReport這個(gè)名字下,包含著DirectReport0,DirectReport1,DirectReport2...這些較小的集合。
DirectReport0 是Employee和錨點(diǎn)結(jié)合的產(chǎn)物;
DirectReport1 是Employee和 DirectReport0 結(jié)合的產(chǎn)物;
依次類推, DirectReport n是Employee和DirectReport n-1結(jié)合的產(chǎn)物;
當(dāng)DirectReport_n為空的時(shí)候,這個(gè)過(guò)程就結(jié)束了。
*** 錨點(diǎn)和DirectReport0,DirectReport1... 的并集就是DirectReport的內(nèi)容。
作為一個(gè)程序員,每次看到遞歸的程序,必然會(huì)想到無(wú)限遞歸這個(gè)錯(cuò)誤。為了避免了在開發(fā)階段,無(wú)限遞歸導(dǎo)致數(shù)據(jù)庫(kù)的崩潰,SQL Server提供了一個(gè)QueryHint, MaxRecursion,可以控制遞歸的***層數(shù),假如超過(guò)這個(gè)數(shù)字而仍為結(jié)束,則視為代碼錯(cuò)誤,強(qiáng)制退出。如:Option(MaxRecursion 10)
可見(jiàn)SQL Server CTEs可以用來(lái)遞歸操作樹形結(jié)構(gòu)的數(shù)據(jù)表。
【編輯推薦】
- SQL Server浮點(diǎn)數(shù)據(jù)類型的詳細(xì)解析
- 卸載SQL Server 2005組件的正確順序
- SQL Server 2000刪除實(shí)戰(zhàn)演習(xí)
- SQL Server存儲(chǔ)過(guò)程的命名標(biāo)準(zhǔn)如何進(jìn)行?
- Server數(shù)據(jù)庫(kù)的臨時(shí)表的正確操作步驟
網(wǎng)站題目:SQLServerCTEs的語(yǔ)法與功能
文章位置:http://m.5511xx.com/article/cccgpcj.html


咨詢
建站咨詢
