Я думаю, что вы хотите пройтись по дереву от листьев к узлам. Это будет:
with recursive cte as (
select id child_id, id parent_id, 1 lvl, parent_id real_parent_id
from descriptor_value dv
where not exists (select 1 from descriptor_value dv1 where dv1.parent_id = dv.id)
union all
select c.child_id, dv.id parent_id, lvl + 1, dv.parent_id
from cte c
inner join descriptor_value dv on dv.id = c.real_parent_id
)
select child_id, parent_id, lvl from cte order by lvl
Якорь рекурсивного запроса начинается со строк, которые не являются родительскими для любого другого узла. Затем мы поднимаемся вверх по дереву, увеличивая lvl
на каждом шаге, пока не достигнем root.
Демонстрация по DB Fiddle :
child_id | parent_id | lvl
-------: | --------: | --:
3 | 3 | 1
3 | 2 | 2
3 | 1 | 3
Если вы хотите начать с любого узла, то это еще проще: нам просто нужно изменить определение якоря:
with recursive cte as (
select id child_id, id parent_id, 1 lvl, parent_id real_parent_id
from descriptor_value dv
union all
select c.child_id, dv.id parent_id, lvl + 1, dv.parent_id
from cte c
inner join descriptor_value dv on dv.id = c.real_parent_id
)
select child_id, parent_id, lvl from cte order by child_id, lvl
Доходность :
child_id | parent_id | lvl
-------: | --------: | --:
1 | 1 | 1
2 | 2 | 1
2 | 1 | 2
3 | 3 | 1
3 | 2 | 2
3 | 1 | 3