我想要一个递归视图,该视图报告给定组的所有子级,每行一个。
我已经尝试了postgres文档中的基本示例,并进行了修改,以尝试在每个递归步骤中返回多行,但是我一直以无限循环结尾。
样本数据
create table groups (
group_id varchar,
parent_id varchar
);
insert into groups (group_id, parent_id) values
('A',NULL),
('B','A'),
('C','B'),
('D','C'),
('E','A')
;
-- A
-- / \
-- E B
-- \
-- C
-- \
-- D
select * from groups;
group_id |parent_id
---------|----------
A |[NULL]
B |A
C |B
D |C
E |A
我想要一个递归视图,该视图报告给定组的每个孩子,每行一个。
目标输出
垂直空白只是为了清楚。
select * from group_recursive;
group_id | parent_id | all_children_ids
---------|-----------|-----------------
A | NULL | A
B | A | B
B | A | A
E | A | E
E | A | A
C | B | C
C | B | B
C | B | A
D | C | D
D | C | C
D | C | B
D | C | A
select * from group_recursive where all_children_ids = 'A';
A | NULL | A
B | A | A
E | A | A
C | B | A
D | C | A
select * from group_recursive where all_children_ids = 'B';
B | A | A
C | B | A
D | C | A
select * from group_recursive where all_children_ids = 'D';
D | C | D
我必须假设这是一个视图,但如有必要,我可以更改为定义函数或其他内容。
感谢您的任何帮助,谢谢!
您可以通过以下查询获取给定组的所有子级:
with recursive cte as (
select group_id, parent_id, group_id root_id, 0 lvl from groups where group_id = ?
union all
select g.group_id, g.parent_id, c.root_id, c.lvl + 1
from groups g
inner join cte c on c.group_id = g.parent_id
)
select * from cte order by lvl, group_id
问号应替换为您要展示其孩子的组。 all_children
看起来像是违反直觉的列名,所以我将其重命名为root_id
。另外,我添加了一个列lvl
,该列指示每个组相对于根的深度。
另一方面,如您要从给定节点向上生成所有路径,如第一个结果集中所示,可以向上遍历树:
with recursive cte as (
select group_id, parent_id, group_id root_id, 0 lvl from groups
union all
select g.group_id, g.parent_id, c.root_id, c.lvl + 1
from groups g
inner join cte c on c.group_id = g.parent_id
)
select group_id, parent_id, root_id from cte order by group_id, parent_id, lvl