递归查询以查找父记录

时间:2011-10-04 17:21:16

标签: sql tsql sql-server-2008

  

基于最高级别和相应的childID记录   即71在这里,我需要一直上升到1并获得   相应的childID记录,即209

     

例如:

     

找到71的子记录:

     

level4 parent - 154,level3 parent - 192,level2 parent - 209     或者1级孩子 - 209

     

209是必要的答案。

     

现在棘手的部分是最高级别是可变的。我的查询   上面显示的不起作用,因为水平会增加到6或7   不知道所需的连接数。

     

我们可以在递归CTE中轻松完成吗?

declare @t table (
 childID int,
 ParentID int,
 level int
)

insert into @t
select 71, 154, 4
union
select 154, 192, 3
union
select 192, 209, 2
union
select 209, 0, 1

select * from @t

select t1.childID, t4.ChildID
from @t t1
inner join
@t t2
on t1.ParentID = t2.childID
inner join
@t t3
on t2.ParentID = t3.childID
inner join
@t t4
on t3.ParentID = t4.childID
and t1.childID = 71

-- I tried to with recursive CTE

declare @t table (
 childID int,
 ParentID int,
 level int
)

insert into @t
select 71, 154, 4
union
select 154, 192, 3
union
select 192, 209, 2
union
select 209, 0, 1

select * from @t

select t1.childID, t4.ChildID
from @t t1
inner join
@t t2
on t1.ParentID = t2.childID
inner join
@t t3
on t2.ParentID = t3.childID
inner join
@t t4
on t3.ParentID = t4.childID
and t1.childID = 71

2 个答案:

答案 0 :(得分:2)

试试这个:

declare @t table (
 childID int,
 ParentID int,
 level int
)

insert into @t
select 71, 154, 4
union
select 154, 192, 3
union
select 192, 209, 2
union
select 209, 0, 1

Declare @SearchChild int
set @SearchChild=71

  ;with MyCTE as (
      select t1.childID, t1.ParentID , @SearchChild AS searchChild, t1.level
        from @t t1 
        where t1.childID = @SearchChild
      UNION ALL
      select t1.childID, t1.ParentID , c.SearchChild, t1.level
        from @t t1
        inner join MyCTE c on t1.childID=c.ParentID
  )
select top 1 * from MyCTE order by level asc

输出:

childID     ParentID    searchChild level
----------- ----------- ----------- -----------
209         0           71          1

我不确定你的目标是什么,没有一行有209和71在一起?这是你能做的最好的事情。此外,这个CTE在链条上工作而不是向下,并且应该在大型桌子上工作得更好。

答案 1 :(得分:0)

这是做到这一点的方法:

;with MyCTE as
(
    select childID, ParentID, t1.childID As firstChild, 0 As depth
    from @t t1 
    where t1.level = 1

    UNION ALL

    select t2.childID, t2.ParentID, m.firstChild, m.depth + 1
    from @t t2
    inner join MyCTE m
    on m.childID = t2.ParentID
)
select TOP 1 childID, firstChild  
from MyCTE
ORDER BY depth DESC

给你

childId firstChild
71      209