2017-05-30 208 views
0

比方說,我們已經有了這個表:如何遞歸選擇父元素下的所有子元素?

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

因此,約翰和薩莉對保羅的工作,和保羅的作品簡。

對於SQL查詢,我想給它餵食簡的ID(4),並使其返回回她的所有下屬:

John  1  3 
Sally 2  3 
Paul  3  4 

我還需要爲此查詢遞歸去深達是需要。例如,也許約翰有人爲他工作,所以他們也會被包含在結果中。


您將如何構建此查詢?

回答

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 
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 | 
+------------+----+-----------+