Я думаю, что вы хотите:
with recursive cte as (
select descriptor_value_id, parent_value_id, 1 lvl
from descriptor_value
where descriptor_value_id = 87
union all
select dv.descriptor_value_id, dv.parent_value_id, lvl + 1
from descriptor_value dv
inner join cte c on c.parent_value_id = dv.descriptor_value_id
)
select string_agg(descriptor_value_id::text, '->' order by lvl desc) full_path from cte
Рекурсивный запрос поднимается вверх по дереву, начиная с заданного descriptor_value_id
. Затем внешний запрос генерирует полный путь путем объединения идентификаторов, найденных в обратном порядке, по мере их обнаружения.
Это дает вам результат с одной строкой и одним столбцом, который содержит полный путь к данному узлу.
Вы можете изменить начальный узел, изменив предложение where
якоря рекурсивного запроса.
Если вы хотите использовать один и тот же лог c, чтобы получить путь к каждому узлу сразу, все еще обходя дерево вверх, вы можете сделать:
with recursive cte as (
select descriptor_value_id starting_id, descriptor_value_id, parent_value_id, 1 lvl
from descriptor_value
union all
select c.starting_id, dv.descriptor_value_id, dv.parent_value_id, lvl + 1
from descriptor_value dv
inner join cte c on c.parent_value_id = dv.descriptor_value_id
)
select
starting_id,
string_agg(descriptor_value_id::text, '->' order by lvl desc) full_path
from cte
group by starting_id
Однако в этом случае может быть проще и эффективнее ходить по дереву вниз.