Recursive query challenge - simple parent/child example

前端 未结 3 1032
灰色年华
灰色年华 2020-12-28 21:05

Note: with help from RhodiumToad on #postgresql, I\'ve arrived at a solution, which I posted as answer. If anyone can improve on this, please chime in!

I have not be

3条回答
  •  悲哀的现实
    2020-12-28 21:25

    I see two problems with the query:

    1. the non-recursive part does not specify the root node. You need to either explicitely select that using WHERE descendant_node_id = 14 or "dynamically" using:

      SELECT ..
      FROM   node_relations nr1
      WHERE  NOT EXISTS (SELECT 1
                         FROM node_relations nr2
                         WHERE nr2.ancestor_node_id = nr1.descendant_node_id)
      
    2. with the correct starting point, the path is not complete as it will miss the final node during the aggregation in the recursive part. So in the outer query you need to append ancestor_node_id to the generated path.

    So the query would look like this:

    WITH RECURSIVE node_graph AS (
       SELECT nr1.id, nr1.ancestor_node_id, nr1.descendant_node_id, ARRAY[nr1.descendant_node_id] AS path, 0 as level
       FROM   node_relations nr1
       WHERE  NOT EXISTS (SELECT 1
                          FROM node_relations nr2
                          WHERE nr2.ancestor_node_id = nr1.descendant_node_id)
    
       UNION  ALL
    
       SELECT nr.id, nr.ancestor_node_id, nr.descendant_node_id, nr.descendant_node_id || ng.path, ng.level + 1 as level
       FROM node_relations nr
         JOIN node_graph ng ON ng.ancestor_node_id = nr.descendant_node_id
    
    )
    SELECT ancestor_node_id||path as path, -- add the last element of the sub-tree to the path
           level as depth
    FROM   node_graph
    ORDER  BY level
    

    Here is the SQLFiddle: http://sqlfiddle.com/#!15/e646b/3

提交回复
热议问题