Question

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:

  • Data model is multi-level tree.
  • TREE_GID is group of tree. It can have more than 1 tree.
  • NODE_ID is unique number in each TREE_GID.
  • TREE_NAME show in root node only.

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?

Was it helpful?

Solution

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;

An SQLfiddle to test both.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top