我有两张桌子:
我需要通过子值获得完整的层次结构。我可以通过以下方式通过一个特定的子节点来完成它:
;with tree as
(
select id, parent_id, name, level from f_all where id = @specefic_id
union all
select f.id, f.parent_id, f.name, f.level from f_all f
inner join tree t on f.id = t.parent_id and f.id <> f.parent_id
)
select *
from tree
OPTION (Maxrecursion 0)
我有一个想法,但我认为这不好。我的想法是使用上面的代码创建函数。并通过选择我的第二个表来调用它。我甚至没有尝试过。你能给我一个正确的方向。
答案 0 :(得分:1)
这是2012+(使用concat()...轻松转换)。
Declare @f_all table (id int,parent_id int,name varchar(50))
Insert into @f_all values
(1,null,'1'),(2,1,'2'),(3,1,'3'),(4,2,'4'),(5,2,'5'),(6,3,'6'),(7,null,'7'),(8,7,'8')
Declare @Top int = null --<< Sets top of Hier Try 9
Declare @Nest varchar(25) = '|-----' --<< Optional: Added for readability
Declare @Filter varchar(25) = '4,6' --<< Empty for All or try 4,6
;with cteP as (
Select Seq = cast(1000+Row_Number() over (Order by name) as varchar(500))
,ID
,parent_id
,Lvl=1
,name
From @f_all
Where IsNull(@Top,-1) = case when @Top is null then isnull(parent_id,-1) else ID end
Union All
Select Seq = cast(concat(p.Seq,'.',1000+Row_Number() over (Order by r.name)) as varchar(500))
,r.ID
,r.parent_id
,p.Lvl+1
,r.name
From @f_all r
Join cteP p on r.parent_id = p.ID)
,cteR1 as (Select *,R1=Row_Number() over (Order By Seq) From cteP)
,cteR2 as (Select A.Seq,A.ID,R2=Max(B.R1) From cteR1 A Join cteR1 B on (B.Seq like A.Seq+'%') Group By A.Seq,A.ID )
Select Distinct
A.R1
,B.R2
,A.ID
,A.parent_id
,A.Lvl
,name = Replicate(@Nest,A.Lvl-1) + A.name
From cteR1 A
Join cteR2 B on A.ID=B.ID
Join (Select R1 From cteR1 where IIF(@Filter='',1,0)+CharIndex(concat(',',ID,','),concat(',',@Filter+','))>0) F on F.R1 between A.R1 and B.R2
Order By A.R1
返回(@ Top = null和@ Filter ='4,6')
返回Full Hier(@ Top = null和@Filter ='')
只返回一部分(@ Top = 2和@Filter ='')
答案 1 :(得分:0)
对我来说,问题是我不知道cte递归是如何工作的。现在我知道它是如何逐行工作的:Recursive Queries Using Common Table Expressions。 下面的代码按子节点返回所有层次结构:
;with tree as(
select id, parent_id, name, level from f_all fa
inner join @2nd_table_cildren_id c on c.id = fa.id
union all
select f.id, f.parent_id, f.name, f.level from f_all f
inner join tree t on f.id = t.parent_id and f.id <> f.parent_id
)
select distinct *
from tree
OPTION (Maxrecursion 0)