Riy*_*lly 2 sql-server-2005 sql-server recursive
我有一个像这样的分层数据表:
BookGroupID GroupName ParentGroupID
----------- --------- -------------
0 Primary 0
1 abc 0
2 abd 0
3 abe 0
4 cbc 1
5 ceg 2
6 cjd 3
7 hjd 5
8 bjy 5
9 mfs 4
10 ikl 7
11 hjy 8
12 mnf 5
13 aws 10
14 qws 11
15 aqe 13
Run Code Online (Sandbox Code Playgroud)
我想在层次结构中选择一个特定的 BookGroupID 及其所有直接和间接子级。例如,对于 2 的 BookGroupID,输出应如下所示:
BookGroupID
-----------
2
5
7
8
10
11
12
13
14
15
Run Code Online (Sandbox Code Playgroud)
解释一下,第 5 行在输出中,因为它是第 2 行的直接孩子,第 7、8 和 12 行是第 5 行的直接孩子,第 15 行是第 13 行的孩子,这是第 10 行的孩子,也是第 7 行的孩子, 14 是 11 的孩子,是 8 的孩子。
那么,我怎样才能在 SQL 中做到这一点呢?
要使用的技术称为递归公用表表达式或递归 CTE。Microsoft SQL 文档很全面,有很多第三方博客文章可以帮助解释。
这是您的特定问题的实现。
这部分只是从您的问题中创建示例数据。它使用临时表(使用# 符号的表)
create table #t (BookGroupID int, GroupName varchar(100), ParentGroupID int)
insert into #t
values
(0 ,'Primary', 0 ),
(1 ,'abc', 0 ),
(2 ,'abd', 0 ),
(3 ,'abe', 0 ),
(4 ,'cbc', 1 ),
(5 ,'ceg', 2 ),
(6 ,'cjd', 3 ),
(7 ,'hjd', 5 ),
(8 ,'bjy', 5 ),
(9 ,'mfs', 4 ),
(10 ,'ikl', 7 ),
(11 ,'hjy', 8 ),
(12 ,'mnf', 5 ),
(13 ,'aws', 10),
(14 ,'qws', 11),
(15 ,'aqe', 13);
Run Code Online (Sandbox Code Playgroud)
这是开始寻找的价值:
declare @parent int = 2;
Run Code Online (Sandbox Code Playgroud)
这就是递归 CTE。您不必像本例中那样将其称为“cte”。最初的分号是多余的。如果程序员懒惰,它可以确保上一条语句正确结束。离开它没有坏处。
;with cte
as (select BookGroupId
from #t as t
where BookGroupId = @parent
UNION ALL
select t.BookGroupId
from #t as t
join cte
on t.ParentGroupId = cte.BookGroupId)
select *
from cte
order by BookGroupId;
Run Code Online (Sandbox Code Playgroud)