繁体   English   中英

Postgres递归CTE与Group?

[英]Postgres recursive CTE with Group?

我试图找出masterIds作为数组。 请在下面找到

create temp table location as
select 1 as id,'World' as name,null as main_id
union all
select 2,'Asia',1
union all
select 3,'Africa',1
union all
select 4,'India',2
union all
select 5,'Sri Lanka',2
union all
select 6,'Mumbai',4
union all
select 7,'South Africa',3

表如

ID 姓名 主要标识
1 世界 null
2 亚洲 1
3 非洲 1
4 印度 2
5 斯里兰卡 2
6 孟买 4
7 南非 3
8 开普敦 7

我的预期结果如下:

ID 姓名 主要标识 MasterIds Arrayint
1 世界 null 1
2 亚洲 1 1,2
3 非洲 1 1,3
4 印度 2 1,2,4
5 斯里兰卡 2 1,2,5
6 孟买 4 1,2,4,6
7 南非 3 1,3,7
8 开普敦 7 1,3,7,8

而且我的代码只处理一行,但我需要整个表格。 请在下面找到我的代码:

 with recursive
    cte as (
    select * from location  where id=4
    union all
    select g.*  from cte join location g on g.id  = cte.main_id
    )
    select array_agg(id)  from cte l

您似乎想要每个 id 的所有祖先(包括 id)的数组。 这是一种尝试:

with recursive cte as (
    select id, name, main_id from location
    union all
    select cte.id, g.name, g.main_id  
    from cte join location g on g.id  = cte.main_id
)
select id, array[id] || array_agg(main_id)  
from cte l
where main_id is not null
group by id

小提琴

对于递归 cte 中的每次迭代,我们保留我们开始的 id 并向上遍历树(即,将下一个祖先添加到祖先集合中)。 最后,我们为每个 id 创建一个组,并将所有祖先聚合到数组中。

值得注意的是,祖先的集合是无序的,因此您最终可能会得到一个无序的“路径”。 您可以通过提供订单来解决这个问题,这里我使用相对于 id 的级别:

 with recursive
    cte as (
    select id, name, main_id, 0 as lvl from location
    union all
    select cte.id, g.name, g.main_id, lvl+1  from cte join location g on g.id  = cte.main_id
    )
    select id, array[id] || array_agg(main_id order by lvl)
    from cte l
    where main_id is not null
    group by id

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM