次のデータが必要です
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 です)。
SQL フィドルのサンプル