模仿 PostgreSQL 中文件夹结构的递归查询

问题描述 投票:0回答:1

我正在尝试使用此表模仿 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 也包含任何子项?

postgresql common-table-expression
1个回答
0
投票
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 结构中的层次结构。

© www.soinside.com 2019 - 2024. All rights reserved.