Postgres:使用 WITH RECURSIVE 构建项目列表及其 parents

Postgres: Using WITH RECURSIVE to build list of item and their parents

我的架构如下所示:

CREATE TABLE category (
  id SERIAL PRIMARY KEY,
  parent INTEGER REFERENCES category(id) DEFERRABLE,
  name TEXT NOT NULL UNIQUE );
SET CONSTRAINTS ALL DEFERRED;

我添加的行是:

INSERT INTO category VALUES (1, NULL, 'animal');
INSERT INTO category VALUES (2, 1, 'dog');
INSERT INTO category VALUES (3, 1, 'cat');
INSERT INTO category VALUES (4, 3, 'siamese');
INSERT INTO category VALUES (5, 3, 'persian');
INSERT INTO category VALUES (6, 7, 'scary1');
INSERT INTO category VALUES (7, 6, 'scary2');

我正在尝试弄清楚如何使用 WITH RECURSIVE 递归查询它以获得如下所示的结果:

   ids   |         names      
---------+------------------------
 {1}     | animal
 {2,1}   | dog, animal
 {3,1}   | cat, animal
 {4,3,1} | siamese, cat, animal
 {5,3,1} | persian, cat, animal
 {6,7}   | scary1, scary2
 {7,6}   | scary2, scary1

其中 ids 是一个包含每个 parent 直到根的数组,其中 names 是一个字符串,每个名称以逗号分隔。 我也需要处理悖论条件不挂。

有人能给我指出正确的方向吗?

由于数据中的循环依赖,您必须检查下一个引用行的 id 是否不存在于 ids 数组中。在最终查询中使用 distinct on (id) 和最大 ids 数组的 select 行。

with recursive categories as (
    select id, parent, array[id] as ids, name as names
    from category
union all
    select cs.id, c.parent, ids || c.id, concat(names, ', ', name)
    from categories cs
    join category c on cs.parent = c.id
    where c.id <> all(ids)
)
select distinct on (id) ids, names
from categories
order by id, cardinality(ids) desc;

   ids   |        names         
---------+----------------------
 {1}     | animal
 {2,1}   | dog, animal
 {3,1}   | cat, animal
 {4,3,1} | siamese, cat, animal
 {5,3,1} | persian, cat, animal
 {6,7}   | scary1, scary2
 {7,6}   | scary2, scary1
(7 rows)