Reputation: 3548
I have a table forumposts with id,parent_forum_post_id and for a given id=1221 I found it's children count.
with recursive all_posts (id, parentid, root_id) as (
select t1.id,
t1.parent_forum_post_id as parentid,
t1.id as root_id
from forumposts t1
union all
select c1.id,
c1.parent_forum_post_id as parentid,
p.root_id
from forumposts c1
join all_posts p on p.id = c1.parent_forum_post_id
)
select (count(*)-1) as child_count
from all_posts
where root_id=1221
group by root_id;
What I need now, is the exact opposite: for a given id, to find out it's level, which is determined by his number of parents(it's parent, and it's parent's parent until it finds null in it's parent parent_forum_post_id column). Hope this makes sense.
Any help is appreciated. Thanks.
Upvotes: 2
Views: 2635
Reputation: 656942
This query can be largely simplified to:
WITH RECURSIVE p AS (
SELECT parent_forum_post_id AS p_id
FROM forumposts
WHERE id = 1221
UNION ALL
SELECT f.parent_forum_post_id
FROM p
JOIN forumposts f ON f.id = p.p_id
)
SELECT count(*) AS level
FROM posts;
Should be considerably faster, too.
Upvotes: 3
Reputation: 1186
If i've understood correctly you want the hierarchy depth of a particular node given its id (root being level 1).This is for postgresql:
with recursive all_posts (id, parentid, node_id) as (
select t1.id,
t1.parent_forum_post_id as parentid,
t1.id as node_id
from forumposts t1
union all
select c1.id,
c1.parent_forum_post_id as parentid,
p.node_id
from forumposts c1
join all_posts p on p.parentid = c1.id
)
select count(*) as level
from all_posts
where node_id=1221
group by node_id;
Upvotes: 2
Reputation: 86735
WITH recursive
anticendent
AS
(
SELECT
id AS post_id,
parent_forum_post_id AS anticendent_post_id,
1 AS distance
FROM
forumposts
UNION ALL
SELECT
anticendent.post_id,
forumposts.parent_forum_post_id,
distance + 1
FROM
anticendent
INNER JOIN
forumposts
ON forumposts.id = anticendent.anticendent_post_id
)
SELECT
post_id,
MAX(distance) AS level
FROM
anticendent
GROUP BY
post_id
WHERE
post_id = 1221
Or...
SELECT
*
FROM
anticendent
WHERE
post_id = 1221
AND anticendent_post_id IS NULL
Upvotes: 2