بدست آوردن برگهای یک درخت توسط Recursive CTE
نویسنده: محمد سلیم آبادی
تاریخ: ۱۳۹۱/۱۱/۱۶ ۱۷:۳۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
گره هایی که با رنگ سبز علامت گذاری شده اند را گرههای برگ مینامیم چون که آن گرهها بدون زیر شاخه هستند.
فرض کنید از ما خواسته شده است با داشتن گره A تمام برگهای این شاخه را بدست بیاوریم.
دو مرحله را باید طی کنیم ابتدا تمام گره هایی که زیر شاخه گره A هستند را باید بدست آورد سپس توسط یک گزاره گرههای برگ را فیلتر کنیم.
در واقع گره هایی برگ هستند که پدر هیچ گرهی دیگری نباشند.
declare @t table
(id char(1) primary key,
parent char(1));
insert @t values
('A',null), --Level 1
('B', 'A'), ('C', 'A'), --Level 2
('D', 'B'), ('E', 'B'),('R','B'), ('F', 'C'), --Level 3
('G', 'D'), --Level 4
('H', 'G'), ('I', 'G'); --Level 5
;with cte as
(
select id, rnk=0 from @t
where parent = 'A'
union all
select t.id, rnk+1
from cte join @t t
on cte.id = t.parent
)
select *
from cte
where not exists
(select *
from @t
where parent = cte.id);
;with cte as
(
select id, rnk=0 from @t
where parent = 'A'
union all
select t.id, rnk+1
from cte join @t t
on cte.id = t.parent
)
select *
from
(
select *, dense_rank() over(order by rnk desc) rk
from cte
)t
where rk = 1
a , ab , ac , abd , abe , abr , abdg , abdgh , ....
declare @t table
(id char(1) primary key,
parent char(1));
insert @t values
('A',null), --Level 1
('B', 'A'), ('C', 'A'), --Level 2
('D', 'B'), ('E', 'B'),('R','B'), ('F', 'C'), --Level 3
('G', 'D'), --Level 4
('H', 'G'), ('I', 'G'); --Level 5
;with cte as
(
select id, rnk=0,
concats = cast(id as varchar(10))
from @t
where parent is null
union all
select t.id, rnk+1,
cast(cte.concats + t.id as varchar(10))
from cte join @t t
on cte.id = t.parent
)
select * from cte
/*
id rnk concats
---- ----------- ----------
A 0 A
B 1 AB
C 1 AC
F 2 ACF
D 2 ABD
E 2 ABE
R 2 ABR
G 3 ABDG
H 4 ABDGH
I 4 ABDGI
*/
;with cte as
(
select id, rnk=0,
concats = cast(id as varchar(10))
from @t
where parent is null
union all
select t.id, rnk+1,
cast(cte.concats + t.id as varchar(10))
from cte join @t t
on cte.id = t.parent
)
select stuff(d.list,1,1,'') as concats
from (select ','+concats
from cte
for xml path(''))d(list)
/*
concats
----------------------------------------
A,AB,AC,ACF,ABD,ABE,ABR,ABDG,ABDGH,ABDGI
*/