Запрос Postgresql для получения отношения родитель-ребенка n-уровня, хранящегося в одной таблице
У меня есть таблица, обозначающая отношения родитель-потомок. Соотношения могут идти n-уровне глубоко.
Я создал образец таблицы, используя следующий запрос:
CREATE SEQUENCE relations_rel_id_seq
INCREMENT BY 1
NO MAXVALUE
NO MINVALUE
CACHE 1;
CREATE TABLE relations(
rel_id bigint DEFAULT nextval('relations_rel_id_seq'::regclass) NOT NULL PRIMARY KEY,
rel_name text,
rel_display text,
rel_parent bigint
);
SQLFiddle
Мне нужно запросить таблицу и показать иерархические отношения родитель-ребенок. Я до сих пор не понимаю, как запросить n-уровневый уровень, используя sql-запрос.
Для sqlfiddle, например, ожидаемая иерархия вывода:
rel1
rel11
rel111
rel112
rel1121
rel2
rel21
rel211
rel212
N.B: Значение n, в n-level
неизвестно.
Конструкция БД:
Есть ли лучший способ, чтобы такое отношение могло быть выражено в базы данных для простого запроса.?
Ответы
Ответ 1
В Postgres вы можете использовать рекурсивное общее табличное выражение:
with recursive rel_tree as (
select rel_id, rel_name, rel_parent, 1 as level, array[rel_id] as path_info
from relations
where rel_parent is null
union all
select c.rel_id, rpad(' ', p.level * 2) || c.rel_name, c.rel_parent, p.level + 1, p.path_info||c.rel_id
from relations c
join rel_tree p on c.rel_parent = p.rel_id
)
select rel_id, rel_name
from rel_tree
order by path_info;
SQLFiddle на основе вашего примера: http://sqlfiddle.com/#!11/59319/19
(Я заменил пробелы для indention символами подчеркивания, поскольку SQLFiddle не отображает пробелы правильно)