Как запросить все узлы между двумя узлами в дереве?
У меня есть иерархическая структура базы данных, например, столбцы ID
а также PARENT_ID
определяется для каждой строки, причем строки верхнего уровня имеют NULL PARENT_ID
,
У меня все отношения из этой таблицы сведены в другую таблицу, например, если бы в одной иерархии деда, родителя, внука было три записи, было бы 3 записи:
**ANCESTOR, DESCENDANT**
grantparent, parent
grandparent, grandchild
parent, grandchild
Вместо того, чтобы выполнять иерархический запрос, чтобы определить, что внук является потомком деда, я могу просто проверить наличие (grandparent, grandchild)
запись в этой сведенной таблице.
Мой вопрос, используя эту уплощенную таблицу, как я могу наиболее эффективно вернуть все записи, которые находятся между двумя узлами. Используя пример, с grandparent
а также grandchild
как мои параметры, как я могу получить обратно (grandparent, parent)
запись.
Я не хочу использовать иерархический запрос для решения этого... Мне интересно, возможно ли это сделать без каких-либо объединений.
3 ответа
SELECT *
FROM mytable
WHERE descendant = @descendant
AND hops <
(
SELECT hops
FROM mytable
WHERE descendant = @descendant
AND ancestor = @ancestor
)
Это автоматически позаботится о случаях, когда @ancestor
на самом деле не @descendant
предок.
Создать индекс на (descendant, hops)
чтобы это работало быстро.
Пытаться:
select h1.descendant intermediate_node
from hierarchy h0
join hierarchy h1
on h0.ancestor = h1.ancestor
and h0.hops > h1.hops -- redundant condition, but may improve performance
join hierarchy h2
on h1.ancestor = h2.ancestor
and h0.descendant = h2.descendant
where h0.ancestor = :ancestor and h0.descendant = :descendant
SELECT
distinct ancestor
FROM
hierarchy
WHERE descendant = :1 AND
ancestor IN (
SELECT
distinct descendant
FROM
hierarchy WHERE ancestor = :2
)