このクエリを使用して、親のコメントを検索します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;
深さを3に制限していることを除いて、それはうまく機能します。現在の行にさらに多くの子があるかどうかを確認するにはどうすればよいですか。 「あとX回ロード」。
これについて最善の方法は何ですか?
this fiddle では、id
4と5には子供がいるので、それらを数えます。
allのすべての子を数えるには、最後の要素への各パスをたどる方法はありません。その後、残りを数えながらshow行をある深さまで表示できます。
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
path[1:2]
は、1番目から2番目の要素までの配列スライスです。 マニュアルの詳細。
これは深さ2で機能します。深さ3で同じようにするには、すべての1:2
を1:3
で置き換えます。
主な機能は、パスの最初のn個の要素で「グループ化」することです。この関連質問で説明されている手法を適用します。
最後のORDER BY
式path <> path[1:2]
は、グループのルート要素(パス全体が先頭の要素と等しい)にのみ当てはまるブール結果を生成し、FALSE
は前にソートしますTRUE
。代わりに単にpath
を使用することもできますが、どちらの方がパフォーマンスが良いかわかりません。