Выберите корневой узел из запроса поддерева (PostgreSQL ltree), который возвращает нескольких потомков - PullRequest
1 голос
/ 20 декабря 2011

Существует ли простой способ выбора корневого узла поддерева (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)

1 Ответ

1 голос
/ 21 декабря 2011

Разве вы не можете просто использовать функцию subpath ()?

SELECT
  SUBPATH(ancestry, 0, 1)
FROM
  some_table;
...