1

私は次のLocation表を持っています

ID  Name       ParentID
-----------------------
1   TopLevel   NULL
2   Region 1   1
3   Fleet 1    2
4   Fleet 2    2

私は最近、この構造を階層アプローチで表示する再帰的 CTE を書き終えました。

TopLevel
-Region 1
--Fleet 1
--Fleet 2

この構造を列階層形式で返すクエリを作成する必要があります。

Level1     Level2   Level3  Level4  Level5  Level6
Top Level
Top Level  Region 1 Fleet 1
Top Level  REgion 1 Fleet 2

場所が行ける深さの最大レベルは 9 です。これを達成するにはどうすればよいですか? 私は再帰的な CTE を使用してそれを構築しようとしていましたが、うまくいかないと思います。他のアイデアはありますか?

4

2 に答える 2

1

ハードコードされた再帰的 CTE を使用して、最大 9 レベルの階層に相当する出力を達成する方法の 1 つを次に示します (必要に応じてテーブル/列参照を実際のオブジェクト名に変更する必要があります。列varchar(50)の実際のタイプがそれよりも広い場合は増加nameします):

with cte as (
  select id, 1 as level,
    name as level1,
    cast(null as varchar(50)) as level2,
    cast(null as varchar(50)) as level3,
    cast(null as varchar(50)) as level4,
    cast(null as varchar(50)) as level5,
    cast(null as varchar(50)) as level6,
    cast(null as varchar(50)) as level7,
    cast(null as varchar(50)) as level8,
    cast(null as varchar(50)) as level9
  from table1 t
  where parentid is null

  union all

  select t.id, cte.level + 1 as level,
    case when level = 0 then t.name else cte.level1 end as level1,
    case when level = 1 then t.name else cte.level2 end as level2,
    case when level = 2 then t.name else cte.level3 end as level3,
    case when level = 3 then t.name else cte.level4 end as level4,
    case when level = 4 then t.name else cte.level5 end as level5,
    case when level = 5 then t.name else cte.level6 end as level6,
    case when level = 6 then t.name else cte.level7 end as level7,
    case when level = 7 then t.name else cte.level8 end as level8,
    case when level = 8 then t.name else cte.level9 end as level9
  from table1 t
  inner join cte on cte.id = t.parentid
)
select * from cte;

サンプル出力:

| ID | LEVEL |   LEVEL1 |   LEVEL2 |  LEVEL3 | LEVEL4 | LEVEL5 | LEVEL6 | LEVEL7 | LEVEL8 | LEVEL9 |
----------------------------------------------------------------------------------------------------
|  1 |     1 | TopLevel |   (null) |  (null) | (null) | (null) | (null) | (null) | (null) | (null) |
|  2 |     2 | TopLevel | Region 1 |  (null) | (null) | (null) | (null) | (null) | (null) | (null) |
|  3 |     3 | TopLevel | Region 1 | Fleet 1 | (null) | (null) | (null) | (null) | (null) | (null) |
|  4 |     3 | TopLevel | Region 1 | Fleet 2 | (null) | (null) | (null) | (null) | (null) | (null) |

デモ: http://www.sqlfiddle.com/#!6/0bd5d/14

于 2013-01-16T19:51:31.587 に答える
0

9 個の UNION ステートメントを使用していることがわかったので、目的の出力が得られるかもしれませんが、きれいではありません。

ここでは 3 つのレベルがあります (それに応じて追加できるはずです)。

SELECT Name as Level1, '' as Level2, '' as Level3
FROM Location
WHERE ParentId IS NULL
UNION
SELECT L1.Name as Level1, L2.Name as Level2, '' as Level3
FROM Location L1
JOIN Location L2 
    ON L1.Id = L2.ParentId 
    AND L1.ParentId IS NULL
UNION
SELECT L1.Name as Level1, L2.Name as Level2, L3.Name as Level3
FROM Location L1
JOIN Location L2 
    ON L1.Id = L2.ParentId 
    AND L1.ParentId IS NULL
JOIN Location L3 
    ON L2.Id = L3.ParentId 
    AND L1.ParentId IS NULL

などなど、後続の各レベルの結合にさらにテーブルを追加します。頭のてっぺんから思いついたのは、より良い/より簡単な方法があるようです。

これがフィドルです。

于 2013-01-16T19:53:51.400 に答える