I have a table with a hierarchical structure:
JavaScript
x
_________
|Plans |_____________________________________________
|-------------------------------------------------------|
| id | parent | plan_name | description |
|-------------------------------------------------------|
| 1 0 Painting bla..bla |
| 2 1 Shopping bla..bla |
| 3 1 Scheduling bla..bla |
| 4 2 Costumes bla..bla |
| 5 2 Tools bla..bla |
| 6 2 Paints bla..bla |
|_______________________________________________________|
I want to list all parents of the plan name Paints
, so I can build a breadcrumb to navigate back. Using id = 6
I like to get:
JavaScript
Painting > Shopping > Paints
I’m using postgresql with PHP, and thinking of efficient way to fetch all the parents as simple as possible.
Advertisement
Answer
Use recursive with query:
JavaScript
with recursive pl(id, parent, parents) as (
select id, parent, array[parent]
from plans
union
select pl.id, plans.parent, pl.parents|| plans.parent
from pl
join plans on pl.parent = plans.id
)
select distinct on (id) id, parents
from pl
order by id, array_length(parents, 1) desc
id | parents
----+---------
1 | {0}
2 | {1,0}
3 | {1,0}
4 | {2,1,0}
5 | {2,1,0}
6 | {2,1,0}
(6 rows)
Instead of integer array of parent ids you can use text column to aggregate plan names:
JavaScript
with recursive pl(id, parent, parents, depth) as (
select id, parent, plan_name, 0
from plans
union
select pl.id, plans.parent, plans.plan_name|| ' > ' ||pl.parents, depth+ 1
from pl
join plans on pl.parent = plans.id
)
select distinct on (id) id, parents
from pl
order by id, depth desc;
id | parents
----+--------------------------------
1 | Painting
2 | Painting > Shopping
3 | Painting > Scheduling
4 | Painting > Shopping > Costumes
5 | Painting > Shopping > Tools
6 | Painting > Shopping > Paints
(6 rows)