在递归 CTE 中计算父级的子级

Mik*_*ike 2 postgresql cte recursive

我使用此查询来查找父母的评论id

WITH RECURSIVE cte (id, content, path, parent_id, depth)  AS (
    SELECT  id,
        content,
        array[id] AS path,
        parent_id,
        1 AS depth
    FROM    comment
    WHERE   id = 1

    UNION ALL

    SELECT  comment.id,
        comment.content,
        cte.path || comment.id,
        comment.parent_id,
        cte.depth + 1 AS depth
    FROM    comment
    JOIN cte ON comment.parent_id = cte.id
    WHERE depth < 3
    )
    SELECT id, content, path, parent_id, depth FROM cte
ORDER BY path LIMIT 200;
Run Code Online (Sandbox Code Playgroud)

除了我将深度限制为 3 之外,它运行良好。我怎样才能知道当前行是否有更多的孩子,如果有,请获取它们的数量,以便我可以显示数字,例如。“多加载 X”。

解决这个问题的最佳方法是什么?

这个小提琴中id4 和 5 有孩子,所以我想数一数。

Erw*_*ter 5

要计算所有子元素,无法绕过每个路径到最后一个元素。然后,您可以在计算其余行的同时将行显示到某个深度:

WITH RECURSIVE cte AS (
   SELECT id, parent_id, content, array[id] AS path
   FROM   comment
   WHERE  id = 1

   UNION ALL
   SELECT c.id, c.parent_id, c.content, cte.path || c.id
   FROM   comment c
   JOIN   cte ON c.parent_id = cte.id
   )
SELECT DISTINCT ON (path[1:2])
       id, parent_id, content, path
     , count(*) OVER (PARTITION BY path[1:2]) - 1 AS children
FROM   cte
ORDER  BY path[1:2], path <> path[1:2]
LIMIT  200;  -- arbitrary limit, unrelated to the question
Run Code Online (Sandbox Code Playgroud)

SQL 小提琴。

path[1:2]是从第一个元素到第二个元素的数组切片手册中的详细信息。

这适用于 2 的深度。 替换所有出现的1:2with1:3以对 3 等的深度执行相同的操作。

主要特征是按路径的前 n 个元素“分组”。应用此相关问题中列出的技术:

最后一个ORDER BY表达式path <> path[1:2]产生一个布尔结果,该结果仅对组的根元素(其中整个路径等于前导元素)为真,并FALSE在 之前排序TRUE。您可以简单地使用path- 不确定哪个性能更好。