如何递归选择父元素下的所有子元素?

时间:2017-05-30 18:26:40

标签: tsql

假设我们有这张表:

WORKER  
NAME     ID    ManagerID  
------------------------
John     1     3  
Sally    2     3  
Paul     3     4  
Jane     4     5  
Jennifer 5     8  

约翰和莎莉为保罗工作,保罗为简工作。

对于SQL查询,我想提供Jane的ID(4)并让它返回所有下属:

John     1     3  
Sally    2     3  
Paul     3     4

我还需要这个查询以递归方式尽可能深入。例如,也许John有人为他工作,所以他们也会被包括在结果中。

您将如何构建此查询?

3 个答案:

答案 0 :(得分:1)

此页面显示了如何使用TSQL将其组合在一起:

https://technet.microsoft.com/en-us/library/ms186243(v=sql.105).aspx

答案 1 :(得分:1)

Declare @YourTable Table ([NAME] varchar(50),[ID] varchar(50),[ManagerID] varchar(50))
Insert Into @YourTable Values
 ('John',1,3)
,('Sally',2,3)
,('Paul',3,4)
,('Jane',4,5)
,('Jennifer',5,8)
,('Boss',8,null) 


Declare @Top    int         = 4      --<<  NULL for Full Hier
Declare @Nest   varchar(25) = '|-----'  --<<  Optional: Added for readability

;with cteP as (
      Select Seq  = cast(10000+Row_Number() over (Order by Name) as varchar(500))
            ,ID
            ,ManagerId 
            ,Lvl=1
            ,Name 
      From   @YourTable 
      Where  IsNull(@Top,-1) = case when @Top is null then isnull(ManagerId ,-1) else ID end
      Union  All
      Select Seq  = cast(concat(p.Seq,'.',10000+Row_Number() over (Order by r.Name)) as varchar(500))
            ,r.ID
            ,r.ManagerId 
            ,p.Lvl+1
            ,r.Name 
      From   @YourTable r
      Join   cteP p on r.ManagerId  = p.ID)
Select A.ID
      ,A.ManagerId 
      ,A.Lvl
      ,Name = Replicate(@Nest,A.Lvl-1) + A.Name
 From  cteP A
 Order By Seq

返回

ID  ManagerId   Lvl Name
4   5           1   Jane
3   4           2   |-----Paul
1   3           3   |-----|-----John
2   3           3   |-----|-----Sally

答案 2 :(得分:1)

您可以使用简单的递归cte,如下所示:

;With cte as (
    Select * from YourWorker where ManagerId = 4

    union all

    select y.WorkerName, y.Id, y.ManagerId from YourWorker y inner join cte c
    on y.ManagerId = c.Id
)
select * from cte

输出如下:

+------------+----+-----------+
| WorkerName | Id | ManagerId |
+------------+----+-----------+
| Paul       |  3 |         4 |
| John       |  1 |         3 |
| Sally      |  2 |         3 |
+------------+----+-----------+