我的架构看起来像这样:
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
是一个包含每个父项的数组,直到根,其中names
是一个字符串,每个名称用逗号分隔。
我还需要处理悖论条件而不会挂起。
有人能指出我正确的方向吗?
答案 0 :(得分:2)
由于数据中存在循环依赖关系,因此必须检查id
数组中是否已存在下一个引用行的ids
。在最终查询中使用distinct on (id)
,然后选择包含最大ids
数组的行。
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)