2012-04-30 40 views
2

我有一個表forumposts與id,parent_forum_post_id和給定的id = 1221我發現它是兒童數。獲取葉級遞歸選擇

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; 

我現在需要的是什麼,是完全相反的:對於給定的ID,找出它的水平,這是由他的父母的數量(它的父,這是父親的父親,直到找到空在它的確定父母parent_forum_post_id列)。希望這是有道理的。

任何幫助表示讚賞。謝謝。

回答

1

如果我理解正確,您想給它的ID(根存在1級)的特定節點的層次深度。這是一個針對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; 
2
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 

或...

SELECT 
    * 
FROM 
    anticendent 
WHERE 
    post_id = 1221 
    AND anticendent_post_id IS NULL 
+0

嗨,感謝您的幫助。但是,我得到這個專欄anticendent.parent_forum_post_id不存在。在postgresql中也是遞歸的。 – Fofole

+0

@Fofole - 是的,我的錯。這是在循環部分的加入。應加入'anticendent_post_id'。更正。 – MatBailie

+0

+1這是一個很好的答案。 – Fofole

3

該查詢可以在很大程度上簡化爲:

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; 

也應該快得多。