Reputation: 3
Assume I have a table that has the following structure:
---------------------------------------------------
TREE_GID | NODE_ID | PARENT_NODE_ID | TREE_NAME |
---------------------------------------------------
1 | 1 | | A |
1 | 2 | 1 | |
1 | 3 | 1 | |
1 | 4 | 2 | |
1 | 5 | 4 | |
1 | 6 | | B |
1 | 7 | 6 | |
2 | 1 | | C |
2 | 2 | 1 | |
---------------------------------------------------
Note:
I would like to display TREE_NAME in each nodes. The output should be like:
---------------------------------
TREE_ID | NODE_ID | TREE_NAME |
---------------------------------
1 | 1 | A |
1 | 2 | A |
1 | 3 | A |
1 | 4 | A |
1 | 5 | A |
1 | 6 | B |
1 | 7 | B |
2 | 1 | C |
2 | 2 | C |
---------------------------------
How can I get them?
Upvotes: 0
Views: 1785
Reputation: 180917
A recursive common table expression will do it in a fairly straight forward way;
WITH cte(tree_gid, node_id, tree_name) AS (
SELECT tree_gid, node_id, tree_name FROM mytable WHERE tree_name IS NOT NULL
UNION ALL
SELECT m.tree_gid, m.node_id, cte.tree_name
FROM mytable m
JOIN cte ON cte.node_id = m.parent_node_id AND cte.tree_gid = m.tree_gid
)
SELECT * FROM cte
ORDER BY tree_gid, node_id;
EDIT: You could also use CONNECT BY
as your commented link describes;
SELECT tree_gid, node_id, CONNECT_BY_ROOT tree_name
FROM mytable
START WITH tree_name IS NOT NULL
CONNECT BY PRIOR node_id = parent_node_id AND PRIOR tree_gid = tree_gid
ORDER SIBLINGS BY tree_gid, node_id;
Upvotes: 1