我需要以下数据
ID 1 2 3 4 5
--- ------------ ------------ ------------ ------------ -----------
1 NULL NULL NULL NULL Level 1
2 NULL NULL NULL Level 1 Level 2
3 NULL NULL Level 1 Level 2 Level 3
4 NULL Level 1 Level 2 Level 3 Level 4
5 Level 1 Level 2 Level 3 Level 4 Level 5
转换为:
ID Level1 Level2 Level3 Level4 Level5
--- ------------ ------------ ------------ ------------ ------------
1 Level 1 NULL NULL NULL NULL
2 Level 1 Level 2 NULL NULL NULL
3 Level 1 Level 2 Level 3 NULL NULL
4 Level 1 Level 2 Level 3 Level 4 NULL
5 Level 1 Level 2 Level 3 Level 4 Level 5
即。在每一行中,1,2,3,4,5
列的数据向左移动了将第一个非空值放入第一个位置所需的多个位置。
数据源自自引用表:
create table data (ID int not NULL, ParentID int, Name varchar(50))
通过将以下语句(包装到表值函数)应用于此表中的记录子集:
with Path(ID, ParentID, Name, Level)
as
(
select ID, ParentID, Name, 0 from data where ID = @id
union all
select d.ID, d.ParentID, d.Name, p.Level-1
from data d
join Path p on p.ParentID = d.ID
)
select
[1], [2], [3], [4], [5]
from
(select 5 + Level as Level, Name from Path) s
pivot (max(Name) for Level in ([1], [2], [3], [4], [5])) p
目前,在数据轮转后,这一转换是通过一堆case
运算符实现的。但我觉得也许应该在旋转之前做一些事情(使它更优雅和/或更有效)。
理想情况下,我想在这里看到尽可能多的解决此任务的方法(在转动之前或之后的任何更改,无关紧要)。
已知级别数和常量(在这种情况下等于5)。
答案 0 :(得分:0)
SQL Fiddle非常有用。我通过改变功能获得了你想要的东西。这是修订后的功能:
create function ftInfo_new(@id int)
returns table as
return
with Path(ID, ParentID, Name, Level) as
(select ID, ParentID, Name, 0
from data
where ID = @id
union all
select d.ID, d.ParentID, d.Name, p.Level-1
from data d join
Path p
on p.ParentID = d.ID
)
select [1], [2], [3], [4], [5]
from (select 1 - Level as Level, Name
from Path
) s
pivot (max(Name) for Level in ([1], [2], [3], [4], [5]));
您也可以通过增加级别而不是减少级别来执行此操作:
create function ftInfo_new(@id int)
returns table as
return
with Path(ID, ParentID, Name, Level)
as
(
select ID, ParentID, Name, 1
from data
where ID = @id
union all
select d.ID, d.ParentID, d.Name, p.Level+1
from data d join
Path p
on p.ParentID = d.ID
)
select [1], [2], [3], [4], [5]
from (select Level as Level, Name
from Path
) s
pivot (max(Name) for Level in ([1], [2], [3], [4], [5])) p