【发布时间】:2021-12-07 19:26:33
【问题描述】:
我正在尝试创建一个 JSON 表示任意深度和广泛的层次结构,例如生物:
CREATE TABLE creatures (
name text PRIMARY KEY,
parent text REFERENCES creatures(name)
);
INSERT INTO creatures(name,parent)
VALUES
('amoeba',NULL),
('beetle','amoeba'),
('coelacanth','amoeba'),
('salmon','coelacanth'),
('tuna','coelacanth'),
('lizard','coelacanth'),
('t-rex','lizard'),
('plant',NULL);
我想把它变成这样的 JSON:
[{"name":"amoeba",
"children": [{"name": "beetle",
"children": []},
{"name": "coelacanth",
"children": [{"name": "tuna",
"children": []},
{"name": "salmon",
"children": []}
{"name": "lizard",
"children": [{"name": "t-rex",
"children": []}]}
]}]},
{"name": "plant",
"children": []}]
这可以在 Postgres 中实现吗?
到目前为止我已经尝试过
WITH RECURSIVE r AS
-- Get all the leaf nodes, group by parent.
(SELECT parent,
json_build_object('name', parent,
'children', array_agg(name)) AS json
FROM creatures c
WHERE parent NOTNULL
AND NOT EXISTS
(SELECT 1
FROM creatures c2
WHERE c.name = c2.parent)
GROUP BY parent
UNION
-- Recursive term - go one step up towards the top.
SELECT c.parent,
json_build_object('name', c.parent,
'children', array_agg(c.name)) AS json
FROM r
JOIN creatures c ON r.parent = c.name
GROUP BY c.parent)
SELECT *
FROM r;
但它失败了
ERROR: aggregate functions are not allowed in a recursive query's recursive term
LINE 19: 'children', array_agg(c.name)) AS...
有什么办法可以解决这个问题,或者有其他解决方案可以让我成为我的好树吗?
【问题讨论】:
-
使用递归函数。并确保您的
creatures不包含圆形路径…… -
@Bergi。没有圆形路径。正如我在问题中所描述的那样,这就是我想要做的......
-
好吧,但是 Postgres 不知道这一点,所以它拒绝与递归查询进行联合,从而永远生成行……
-
我相信this 是您尝试的查询,但这实际上并不是在做递归
标签: json postgresql