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 级的层次结构(您需要根据需要将表/列引用更改为真实对象名称,并且您可能需要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 回答