这与这里类似。不同的是我想在第一列(左边)显示根
我有一个分层表
categories
如下:
id | 名字 | parent_id |
---|---|---|
1 | 住宿 | 空 |
2 | 交通 | 空 |
3 | 实用工具 | 1 |
4 | 保养 | 1 |
5 | 私人 | 2 |
6 | 公开 | 2 |
7 | 电力 | 3 |
8 | 煤气 | 3 |
9 | 互联网 | 3 |
10 | 花园服务 | 4 |
11 | 维修 | 4 |
12 | 汽车还款 | 5 |
13 | 娱乐 | 空 |
14 | .... | .. |
我想将其转置为每个
leaf
显示一行,如下所示(我知道前面的级别最多为 3),根出现在第一列:
root_id | 根_名称 | child_id_1 | child_name_1 | child_id_2 | child_name_2 | |
---|---|---|---|---|---|---|
1 | 住宿 | 3 | 实用工具 | 9 | 互联网 | |
1 | 住宿 | 3 | 实用工具 | 8 | 煤气 | |
2 | 交通 | 5 | 私人 | 12 | 汽车还款 | |
2 | 交通 | 6 | 公开 | 空 | 空 | |
12 | 娱乐 | 空 | 空 | 空 | 空 | |
.. | .. | .. | .. | .. | .. | .. |
使用 CASE 和 LAST_VALUE 的一种解决方案:
select distinct root_id, root_name,
last_value(child_id1 ignore nulls) over(partition by root_id order by child_id1 ) as child_id1,
last_value(child_name1 ignore nulls) over(partition by root_id order by child_id1) as child_name1,
last_value(child_id2 ignore nulls) over(partition by root_id order by child_id2) as child_id2,
last_value(child_name2 ignore nulls) over(partition by root_id order by child_id2) as child_name2,
last_value(child_id3 ignore nulls) over(partition by root_id order by child_id3) as child_id3,
last_value(child_name3 ignore nulls) over(partition by root_id order by child_id3) as child_name3
from (
select root_id, root_name,
case lvl when 1 then id end as child_id1,
case lvl when 1 then name end as child_name1,
case lvl when 2 then id end as child_id2,
case lvl when 2 then name end as child_name2,
case lvl when 3 then id end as child_id3,
case lvl when 3 then name end as child_name3
from (
select level as lvl, connect_by_root(id) as root_id,
connect_by_root(name) as root_name,
d.*
from data d
connect by prior id = parent_id
)
)
;
与您的其他问题类似;但这一次从识别根节点开始:
With as (
select *
from MyTbl RN
where RN.parent_id is null
)
select RN.*, C1.*,C2.*
from RootNodes RN
left join
MyTbl C1
on RN.id=C1.parent_id
left join
MyTbl C2
on C1.id=C2.parent_id