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”。
解决这个问题的最佳方法是什么?
在这个小提琴中,id
4 和 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)
path[1:2]
是从第一个元素到第二个元素的数组切片。手册中的详细信息。
这适用于 2 的深度。 替换所有出现的1:2
with1:3
以对 3 等的深度执行相同的操作。
主要特征是按路径的前 n 个元素“分组”。应用此相关问题中列出的技术:
最后一个ORDER BY
表达式path <> path[1:2]
产生一个布尔结果,该结果仅对组的根元素(其中整个路径等于前导元素)为真,并FALSE
在 之前排序TRUE
。您可以简单地使用path
- 不确定哪个性能更好。