由儿童获得完整的等级

时间:2016-11-14 18:05:38

标签: sql-server tsql

我有两张桌子:

  1. 包含完整的树数据
  2. enter image description here

    1. 仅包含特定的孩子
    2. 我需要通过子值获得完整的层次结构。我可以通过以下方式通过一个特定的子节点来完成它:

      ;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)
      

      我有一个想法,但我认为这不好。我的想法是使用上面的代码创建函数。并通过选择我的第二个表来调用它。我甚至没有尝试过。你能给我一个正确的方向。

2 个答案:

答案 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')

enter image description here

返回Full Hier(@ Top = null和@Filter ='')

enter image description here

只返回一部分(@ Top = 2和@Filter ='')

enter image description here

答案 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)