Postgresql 如何创建递归cte查询,将父ID和祖父母ID推送到一个数组中

Postgresql 如何创建递归cte查询,将父ID和祖父母ID推送到一个数组中,postgresql,common-table-expression,recursive-query,Postgresql,Common Table Expression,Recursive Query,我正在尝试创建一个postgresql表。这是我的cte,我在这里插入值 BEGIN; CREATE TABLE section ( id SERIAL PRIMARY KEY, parent_id INTEGER REFERENCES section(id) DEFERRABLE, name TEXT NOT NULL UNIQUE ); SET CONSTRAINTS ALL DEFERRED; INSERT INTO section VALUES (1, NULL, 'anim

我正在尝试创建一个postgresql表。这是我的cte,我在这里插入值

BEGIN;
CREATE TABLE section (
  id SERIAL PRIMARY KEY,
  parent_id INTEGER REFERENCES section(id) DEFERRABLE,
  name TEXT NOT NULL UNIQUE );
SET CONSTRAINTS ALL DEFERRED;
INSERT INTO section VALUES (1, NULL, 'animal');
INSERT INTO section VALUES (2, NULL, 'mineral');
INSERT INTO section VALUES (3, NULL, 'vegetable');
INSERT INTO section VALUES (4, 1, 'dog');
INSERT INTO section VALUES (5, 1, 'cat');
INSERT INTO section VALUES (6, 4, 'doberman');
INSERT INTO section VALUES (7, 4, 'dachshund');
INSERT INTO section VALUES (8, 3, 'carrot');
INSERT INTO section VALUES (9, 3, 'lettuce');
INSERT INTO section VALUES (10, 11, 'paradox1');
INSERT INTO section VALUES (11, 10, 'paradox2');
SELECT setval('section_id_seq', (select max(id) from section));

WITH RECURSIVE last_run(parent_id, id_list, name_list) AS (
  ???
SELECT id_list, name_list
FROM last_run ???
WHERE ORDER BY id_list;
ROLLBACK;
我知道递归查询是最好的方法,但不确定如何准确地实现它。到底是怎么回事??? 我想得到的是下表:

id_list |       name_list        
---------+------------------------
 {1}     | animal
 {2}     | mineral
 {3}     | vegetable
 {4,1}   | dog, animal
 {5,1}   | cat, animal
 {6,4,1} | doberman, dog, animal
 {7,4,1} | dachshund, dog, animal
 {8,3}   | carrot, vegetable
 {9,3}   | lettuce, vegetable
 {10,11} | paradox1, paradox2
 {11,10} | paradox2, paradox1

您可以在单个查询中使用多个递归CTE:一个用于有效树,另一个用于悖论:

with recursive
  cte as (
    select *, array[id] as ids, array[name] as names
    from section
    where parent_id is null
    union all
    select s.*, s.id||c.ids, s.name||c.names
    from section as s join cte as c on (s.parent_id = c.id)),
  paradoxes as (
    select *, array[id] as ids, array[name] as names
    from section
    where id not in (select id from cte)
    union all
    select s.*, s.id||p.ids, s.name||p.names
    from section as s join paradoxes as p on (s.parent_id = p.id)
    where s.id <> all(p.ids) -- To break loops
  ) 
select * from cte
union all
select * from paradoxes;
结果:

┌────┬───────────┬───────────┬─────────┬────────────────────────┐ │ id │ parent_id │ name │ ids │ names │ ├────┼───────────┼───────────┼─────────┼────────────────────────┤ │ 1 │ ░░░░ │ animal │ {1} │ {animal} │ │ 2 │ ░░░░ │ mineral │ {2} │ {mineral} │ │ 3 │ ░░░░ │ vegetable │ {3} │ {vegetable} │ │ 4 │ 1 │ dog │ {4,1} │ {dog,animal} │ │ 5 │ 1 │ cat │ {5,1} │ {cat,animal} │ │ 8 │ 3 │ carrot │ {8,3} │ {carrot,vegetable} │ │ 9 │ 3 │ lettuce │ {9,3} │ {lettuce,vegetable} │ │ 6 │ 4 │ doberman │ {6,4,1} │ {doberman,dog,animal} │ │ 7 │ 4 │ dachshund │ {7,4,1} │ {dachshund,dog,animal} │ │ 10 │ 11 │ paradox1 │ {10} │ {paradox1} │ │ 11 │ 10 │ paradox2 │ {11} │ {paradox2} │ │ 11 │ 10 │ paradox2 │ {11,10} │ {paradox2,paradox1} │ │ 10 │ 11 │ paradox1 │ {10,11} │ {paradox1,paradox2} │ └────┴───────────┴───────────┴─────────┴────────────────────────┘ 如您所见,结果包括两个不需要的行:{10}、{paradox1}和{11}、{paradox2}。如何过滤掉它们取决于你

如果在节值12,10,'paradox3'中添加另一行,如INSERT,则不清楚期望的结果是什么;比如说