SQL Server 2005數(shù)據(jù)庫(kù)中表的遞歸查詢(xún)
具體示例如下:
*/
CREATE TABLE CarParts
(
CarID INT NOT NULL,
Part VARCHAR(15),
SubPart VARCHAR(15),
Qty INT
)
GO
INSERT CarParts VALUES (1, 'Body', 'Door', 4)
INSERT CarParts VALUES (1, 'Body', 'Trunk Lid', 1)
INSERT CarParts VALUES (1, 'Body', 'Car Hood', 1)
INSERT CarParts VALUES (1, 'Door', 'Handle', 1)
INSERT CarParts VALUES (1, 'Door', 'Lock', 1)
INSERT CarParts VALUES (1, 'Door', 'Window', 1)
INSERT CarParts VALUES (1, 'Body', 'Rivets', 1000)
INSERT CarParts VALUES (1, 'Door', 'Rivets', 100)
INSERT CarParts VALUES (1, 'Door', 'Mirror', 1)
INSERT CarParts VALUES (1, 'Mirror', 'small_Mirror', 4)
GO
SELECT * FROM CarParts
GO
/*
一輛汽車(chē)需要各個(gè)零件的數(shù)目
1個(gè)Body 需要4個(gè)Door
1個(gè)Door 需要1個(gè)Mirror
那么
1個(gè)body需要4個(gè)Mirror
結(jié)構(gòu)很簡(jiǎn)單吧
*/
WITH CarPartsCTE(SubPart, Qty)
AS
(
-- 固定成員 (AM):
-- SELECT查詢(xún)無(wú)需參考CarPartsCTE
-- 遞歸從此處開(kāi)始
SELECT SubPart, Qty
FROM CarParts
WHERE Part = 'Body'
UNION ALL
-- 遞歸成員 (RM):
-- SELECT查詢(xún)參考CarPartsCTE
-- 使用現(xiàn)有數(shù)據(jù)往下一層展開(kāi)
SELECT CarParts.SubPart, CarPartsCTE.Qty * CarParts.Qty
FROM CarPartsCTE
INNER JOIN CarParts ON CarPartsCTE.SubPart = CarParts.Part
WHERE CarParts.CarID = 1
)
SELECT SubPart,Qty AS TotalNUM
FROM CarPartsCTE
/*
注意看最下層的small_Mirror 位于 表最后的位置,
由此可以看出改遞歸不是開(kāi)始就進(jìn)行遞歸查詢(xún)而是在1層完全展開(kāi)后在根據(jù)該層展開(kāi)下一層不是深度優(yōu)先的遞歸
*/
drop table CarParts
--------------------------------result---------------------------------------
CarID Part SubPart Qty
----------- --------------- --------------- -----------
1 Body Door 4
1 Body Trunk Lid 1
1 Body Car Hood 1
1 Door Handle 1
1 Door Lock 1
1 Door Window 1
1 Body Rivets 1000
1 Door Rivets 100
1 Door Mirror 1
1 Mirror small_Mirror 4
(10 row(s) affected)
SubPart TotalNUM
--------------- -----------
Door 4
Trunk Lid 1
Car Hood 1
Rivets 1000
Handle 4
Lock 4
Window 4
Rivets 400
Mirror 4
small_Mirror 16
(10 row(s) affected)
示例:
以下示例顯示經(jīng)理以及向經(jīng)理報(bào)告的雇員的層次列表。
WITH DirectReports(groupid, member, EmployeeLevel,type) AS
(
SELECT groupid, member, 0,type AS EmployeeLevel
FROM groupinfo
WHERE groupid = 'finance_company'
UNION ALL
SELECT e.groupid, e.member, EmployeeLevel + 1,e.type
FROM groupinfo e
INNER JOIN DirectReports d
ON e.groupid = d.member
)
SELECT b.nickname,groupid, member, EmployeeLevel,type
FROM DirectReports,userbasicinfo b
where DirectReports.member=b.id
and type = 1
