我正在尝试使用此表模仿 PostgreSQL 中的简单文件夹结构:
CREATE TABLE folders (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
name text,
parent UUID REFERENCES folders(id)
);
我有一些简单的数据(id简化):
(1, "parent", NULL)
(2, "child of 1", 1)
(3, "child of 2", 2)
(4, "other parent", NULL)
我使用之前的一些帖子创建了这个递归查询:
WITH RECURSIVE recursive_cte AS (
SELECT id, name, parent
FROM folders
WHERE parent IS NULL -- Start with the root items (where parent is NULL)
UNION ALL
SELECT f.id, f.name, f.parent
FROM folders f
JOIN recursive_cte rc ON f.parent = rc.id
)
SELECT id, name,
(
SELECT json_agg(json_build_object('id', c.id, 'name', c.name))
FROM recursive_cte c
WHERE c.parent = folders.id
) AS children
FROM folders
WHERE parent IS NULL;
我返回的数据是:
id, name, children[]
(1, "parent", [{"id":2, "name":"child of 1"}])
(4, "other parent", [])
修改我的查询需要执行哪些步骤,以便我可以递归地构建“children”列以使 json 也包含任何子项?
WITH RECURSIVE recursive_cte AS (
SELECT id, name, parent, jsonb_build_object('id', id, 'name', name) AS json_data
FROM folders
WHERE parent IS NULL -- Start with the root items (where parent is NULL)
UNION ALL
SELECT f.id, f.name, f.parent, jsonb_build_object('id', f.id, 'name', f.name) || rc.json_data
FROM folders f
JOIN recursive_cte rc ON f.parent = rc.id
)
SELECT id, name, jsonb_agg(json_data) AS children
FROM recursive_cte
GROUP BY id, name
ORDER BY id;
使用 jsonb_build_object 函数为递归公用表表达式中的每个文件夹创建一个 JSON 对象,该 JSON 对象包含文件夹的“id”和“name”,然后使用 ||运算符将当前文件夹的 JSON 数据与其父文件夹的 JSON 数据连接到递归 CTE 中;构建 JSON 结构中的层次结构。