Существует ли простой способ выбора корневого узла поддерева (PostgreSQL ltree) из запроса, который возвращает (потенциально) несколько узлов-потомков того же поддерева? Я реализовал довольно многословный алгоритм для достижения задачи (~ 40 строк, с отступом и отформатирован), но было бы здорово, если бы я мог использовать тот факт, что данные дерева на самом деле являются деревьями и имеют легко доступный корневой узел. Важно отметить, что несколько отдельных корней поддеревьев могут быть возвращены из одного запроса, поэтому я не могу просто отсортировать данные и получить лучший результат.
07 июня 2012 г. Я обновил запрос до последней версии, что вдвое сокращает сложность времени. Он использует само-анти-объединение (если хотите), чтобы удалить все узлы из поддерева, у которых есть предки в поддереве.
По сути, мой алгоритм работает следующим образом:
WITH roots AS
(
/* Place any query here, which returns a field "ancestry" of type ltree */
)
SELECT roots.*
FROM roots
WHERE NOT EXISTS
(
SELECT 1
FROM roots AS ancestors
WHERE ancestors.ancestry @> roots.ancestry
AND ancestors.id <> roots.id
);
(подробнее см. Мою суть здесь: https://gist.github.com/1507368)