Come faccio a query per tutti i nodi tra i due nodi di un albero?
Domanda
Ho uno strucutre database gerarchico, ad esempio, colonne ID
e PARENT_ID
definiti per ogni riga, con le file di livello superiore avente una NULL PARENT_ID
.
Ho tutte le relazioni di questo tavolo appiattito in un'altra tabella, ad esempio, se ci fossero tre record in una singola gerarchia di nonni, genitori, nipoti, ci sarebbero 3 record:
**ANCESTOR, DESCENDANT**
grantparent, parent
grandparent, grandchild
parent, grandchild
Invece di eseguire una query gerarchica di determinare che il nipote è un discendente del nonno posso semplicemente verificare l'esistenza di un record (grandparent, grandchild)
in questa tabella appiattita.
La mia domanda è, usando questa tabella appiattita, come posso tornare in modo più efficiente tutti i record che sono tra due nodi. Utilizzando l'esempio, con grandparent
e grandchild
come i miei parametri, come posso ottenere di nuovo il record (grandparent, parent)
.
Non voglio utilizzare una query gerarchica per risolvere questo ... mi chiedo se è possibile fare questo senza alcun join.
Soluzione
SELECT *
FROM mytable
WHERE descendant = @descendant
AND hops <
(
SELECT hops
FROM mytable
WHERE descendant = @descendant
AND ancestor = @ancestor
)
Questo richiederà automaticamente la cura di casi in cui @ancestor
in realtà non è un antenato di @descendant
.
Crea un indice su (descendant, hops)
per questo di lavorare velocemente.
Altri suggerimenti
Prova:
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
)