我有一张叫做emp的桌子.该表有以下数据.
empid name Manager_id
1 A Null
2 B 1
3 C 2
4 D 2
5 E 4
Run Code Online (Sandbox Code Playgroud)
我希望上表中的输出如下.
empid name Manager_id Level1 Level2 Level3 Level4
1 A null A null null null
2 B 1 A B null null
3 C 2 A B C null
4 D 2 A B D D
5 E 4 A B D E
Run Code Online (Sandbox Code Playgroud)
Mik*_*son 13
with C as
(
select T.EmpID,
T.ManagerID,
T.Name,
cast('' as xml).query('element X { attribute V {sql:column("T.Name")}}') as LvlXML
from YourTable as T
where T.ManagerID is null
union all
select T.EmpID,
T.ManagerID,
T.Name,
C.LvlXML.query('., element X { attribute V {sql:column("T.Name")}}')
from YourTable as T
inner join C
on T.ManagerID = C.EmpID
)
select C.EmpID,
C.Name,
C.ManagerID,
C.LvlXML.value('/X[1]/@V', 'varchar(100)') as Level1,
C.LvlXML.value('/X[2]/@V', 'varchar(100)') as Level2,
C.LvlXML.value('/X[3]/@V', 'varchar(100)') as Level3,
C.LvlXML.value('/X[4]/@V', 'varchar(100)') as Level4,
C.LvlXML.value('/X[5]/@V', 'varchar(100)') as Level5
from C;
Run Code Online (Sandbox Code Playgroud)
更新:
@ t-clausen.dk指出上面的查询的性能不是它可以是这样的,所以这里是一个更快的版本.
首先在ManagerIDwith 上添加索引Name作为包含列.
create index IX_YourTable_ManagerID on YourTable(ManagerID) include(Name)
Run Code Online (Sandbox Code Playgroud)
以及在递归时构建所需列的新查询.
with C as
(
select T.EmpID,
T.ManagerID,
T.Name,
T.Name as Level1,
cast(null as varchar(100)) as Level2,
cast(null as varchar(100)) as Level3,
cast(null as varchar(100)) as Level4,
1 as Lvl
from YourTable as T
where T.ManagerID is null
union all
select T.EmpID,
T.ManagerID,
T.Name,
C.Level1,
case when C.lvl = 1 then T.Name else C.Level2 end,
case when C.lvl = 2 then T.Name else C.Level3 end,
case when C.lvl = 3 then T.Name else C.Level4 end,
C.Lvl + 1
from YourTable as T
inner join C
on T.ManagerID = C.EmpID
)
select C.EmpID,
C.Name,
C.ManagerID,
C.Level1,
C.Level2,
C.Level3,
C.Level4
from C;
Run Code Online (Sandbox Code Playgroud)
这给了你这个很好的小查询计划,在锚点和查询的递归部分都有索引搜索:

| 归档时间: |
|
| 查看次数: |
249 次 |
| 最近记录: |