根据下面的系列记录,如何获得最后一个子记录(ST)给出其位置层次结构的事实。
图例
PM (Project Manager) - is the highest role position
PS (Project Supervisor) - is the down-line of PM
ST (Staff) - is the down-line of PS and the lowest role position
数据
ID Name RoleCode RoleDescription ReportingtoID
1 Will Smith PM Project Manager NULL
2 Zoey Nathan PM Project Manager NULL
3 Louise Norton PS Project Supervisor 1
4 Cynthia Villaz PS Project Supervisor 1
5 Ronald Trimp PS Project Supervisor 2
6 Lebron James ST Staff 3
7 Raymond Trimp ST Staff 4
8 Kevin Garn ST Staff 3
9 Kobe Spars ST Staff 5
10 Paul Lee ST Staff 3
11 Mark Pingris ST Staff 4
12 Elton Horn ST Staff 1
13 Shayne Wyn ST Staff 1
示例1
如果我们要获取 Zoey Nathan(PM)的下线,由于此人没有下线,所以不会反映任何记录。
如果我们要取 Will Smith(PM)的子根,结果应该低于:
以下说明:威尔史密斯有两个下线即路易斯诺顿和辛西娅维拉兹,他们两个也有所不同下线,这都是STAFF的位置。由于STAFF是最低层次,因此应显示所有这些层次结构。此外,还有一个实例,即STAFF也直接向项目经理报告,这就是为什么 Elton Horn 和 Shayne Wyn 都会对结果产生影响。
渴望输出
ID Name RoleCode RoleDescription ReportingtoID
6 Lebron James ST Staff 3
7 Raymond Trimp ST Staff 4
8 Kevin Garn ST Staff 3
10 Paul Lee ST Staff 3
11 Mark Pingris ST Staff 4
12 Elton Horn ST Staff 1
13 Shayne Wyn ST Staff 1
示例2
如果我们要取 Cynthia Villaz(PS)的子根,结果应该如下:
渴望输出
ID Name RoleCode RoleDescription ReportingtoID
7 Raymond Trimp ST Staff 4
11 Mark Pingris ST Staff 4
示例3
如果我们要取 Ronald Trimp(PS)的子根,结果应该如下:
渴望输出
ID Name RoleCode RoleDescription ReportingtoID
9 Kobe Spars ST Staff 5
示例4
如果我们要取 Raymond Trimp(ST)的子根,结果应该如下:
由于ST是最低级别,因此不会显示任何记录。
渴望输出
ID Name RoleCode RoleDescription ReportingtoID
No Record Found
我正在使用SQL Server 2016?需要帮助。有人可以为我做代码然后我会改进它。
答案 0 :(得分:0)
Declare @YourTable table (ID int,Name varchar(50),RoleCode varchar(25),RoleDescription varchar(50),ReportingtoID int)
Insert into @YourTable values
(1 ,'Will Smith' ,'PM' ,'Project Manager' ,NULL),
(2 ,'Zoey Nathan' ,'PM' ,'Project Manager' ,NULL),
(3 ,'Louise Norton' ,'PS' ,'Project Supervisor' ,1),
(4 ,'Cynthia Villaz' ,'PS' ,'Project Supervisor' ,1),
(5 ,'Ronald Trimp' ,'PS' ,'Project Supervisor' ,2),
(6 ,'Lebron James' ,'ST' ,'Staff' ,3),
(7 ,'Raymond Trimp' ,'ST' ,'Staff' ,4),
(8 ,'Kevin Garn' ,'ST' ,'Staff' ,3),
(9 ,'Kobe Spars' ,'ST' ,'Staff' ,5),
(10 ,'Paul Lee' ,'ST' ,'Staff' ,3),
(11 ,'Mark Pingris' ,'ST' ,'Staff' ,4),
(12 ,'Elton Horn' ,'ST' ,'Staff' ,1),
(13 ,'Shayne Wyn' ,'ST' ,'Staff' ,1)
Declare @Top int = null --<< Sets top of Hier Try 1 for Will Smith
Declare @Leaf bit = 0 --<< Toggle Leaf Only
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
,ReportingtoID
,Lvl=1
,Name
,RoleCode
From @YourTable
Where IsNull(@Top,-1) = case when @Top is null then isnull(ReportingtoID ,-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.ReportingtoID
,p.Lvl+1
,r.Name
,r.RoleCode
From @YourTable r
Join cteP p on r.ReportingtoID = p.ID)
,cteR1 as (Select *,R1=Row_Number() over (Order By Seq) From cteP)
,cteR2 as (Select 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 A.R1
,B.R2
,A.ID
,A.ReportingtoID
,A.Lvl
,Name = case when @Leaf = 1 then '' else Replicate(@Nest,A.Lvl-1) end + A.Name
,A.RoleCode
From cteR1 A
Join cteR2 B on A.ID=B.ID
Where A.R1 = case when @Leaf=1 then B.R2 else A.R1 end
Order by case when @Leaf=1 then A.ID else A.R1 end
当@Top = 1且@Leaf = 1时,您将获得以下内容
当@Top = 1且@Leaf = 0时,您将获得嵌套层次结构
当@Top = NULL且@Leaf = 0时,您将获得FULL Hierarchy