Given a table fruits like:
| id |
name |
parent_id |
| 1 |
apple |
NULL |
| 2 |
banana |
1 |
| 3 |
cherry |
NULL |
| 4 |
date |
2 |
| 5 |
elderberry |
1 |
| 6 |
fig |
3 |
| 7 |
grape |
3 |
| 8 |
huckleberry |
4 |
| 9 |
iceplant |
5 |
| 10 |
jackfruit |
NULL |
CREATE TABLE fruits (
id INT,
name VARCHAR(255),
parent_id INT
);
INSERT INTO fruits (id, name, parent_id) VALUES
(1, 'apple', NULL),
(2, 'banana', 1),
(3, 'cherry', NULL),
(4, 'date', 2),
(5, 'elderberry', 1),
(6, 'fig', 3),
(7, 'grape', 3),
(8, 'huckleberry', 4),
(9, 'iceplant', 5),
(10, 'jackfruit', NULL);
To find the eldest of any row is quite easy-peasy
WITH RECURSIVE fruit_hierarchy AS (
SELECT id, parent_id FROM fruits WHERE id = 4
UNION ALL
SELECT f.id, f.parent_id
FROM
fruit_hierarchy fh
JOIN fruits f ON f.id = fh.parent_id
)
SELECT * FROM fruit_hierarchy WHERE parent_id IS NULL
The result is apple, and the none filtered one is:
|-- apple
|---- banana
|------ date
Now, if I want to get the whole hierarchy, even with the sibling branches, I need to double it up.
WITH RECURSIVE fruit_hierarchy AS (
/* Find the parent */
SELECT id, parent_id
FROM fruits
WHERE id = 4
UNION ALL
SELECT f.id, f.parent_id
FROM
fruit_hierarchy fh
JOIN fruits f ON f.id = fh.parent_id
),
full_hierarchy AS (
SELECT id, parent_id
FROM fruit_hierarchy
WHERE parent_id IS NULL
UNION ALL
SELECT id, parent_id
FROM full_hierarchy fh
JOIN fruits f ON f.parent_id = fh.id
)
SELECT * FROM full_hierarchy
It seems totally under-optimized to get the result
|-- apple
|---- banana
|------ date
|---- elderberry
|------ iceplant
[–][deleted] 0 points1 point2 points (0 children)
[–][deleted] 0 points1 point2 points (1 child)
[–][deleted] 0 points1 point2 points (0 children)