Recursively find the path to all leaves descending from a given parent in a tree
3
votes
1
answer
5646
views
I'm trying to write a query to identify the path to each furthest descendant of a particular parent node in a table of tree structures like:
0 1
| |
2 3
| |
4 5
/ \ |
*6* 8 *7*
|
*9*
There are many parents, all children have one parent, parents have 0-5 children (but the graph is very "long" – most parents only have one child). There are no cycles.
I'm trying to efficiently identify the path to the furthest descendants of a specific node (and not to any intermediate nodes). E.g. in the above:
- get_leaf_paths(1)
would return 1 row: {1, 3, 5, 7}
- get_leaf_paths(2)
would return 2 rows: {2, 4, 6}
and {2, 4, 8, 9}
Sample table:
CREATE TABLE graph (
id bigint PRIMARY KEY,
parent_id bigint,
FOREIGN KEY (parent_id) REFERENCES graph(id)
);
INSERT INTO graph (id, parent_id)
VALUES (0, NULL),
(1, NULL),
(2, 0),
(3, 1),
(4, 2),
(5, 3),
(6, 4),
(7, 5),
(8, 4),
(9, 8);
I'm hoping for a result that looks something like:
SELECT get_leaf_paths.* FROM get_leaf_paths(0);
path
-----
{0, 2, 4, 6}
{0, 2, 4, 8, 9}
(2 rows)
In my [initial attempt](https://dba.stackexchange.com/questions/289512/drop-intermediate-results-of-recursive-query-in-postgres) at a function with a recursive query, I've had trouble selecting only the furthest leaves, especially since some branches are shorter than others (e.g. 6
and 9
above are at different depths). The paths can be very deep (thousands or millions of elements), so I would also like to avoid the excessive memory usage of generating paths for every intermediate node.
Any ideas would be greatly appreciated. Thanks!
Asked by Jason Dreyzehner
(155 rep)
Apr 9, 2021, 05:10 AM
Last activity: Apr 9, 2021, 05:58 AM
Last activity: Apr 9, 2021, 05:58 AM