Vous pouvez rendre la recherche du chemin plus efficace si vous commencez par le bas. Commencez par les enfants. Si vous commencez par le parent, cela implique de parcourir tous les enfants; alors que si vous avez cherché à partir de l'enfant, il n'a qu'un seul parent, vous ne perdrez donc pas de temps à trouver le chemin entre la source et la cible.
with recursive find_parent(source, target, recentness) as
(
select source, target, 0
from tbl
where target = 9
union all
select i.source, i.target, fp.recentness + 1
from tbl i
join find_parent fp on i.target = fp.source
),
construct_path(source, target, recentness, path) as
(
select source, target, recentness, source || '.' || target
from find_parent
where recentness = (select max(recentness) from find_parent)
union
select dd.source, dd.target, dd.recentness, cp.path || '.' || dd.target
from find_parent dd
join construct_path cp on dd.recentness = cp.recentness - 1
)
select source, target, path
from construct_path
order by recentness desc
Sortie :
SOURCE TARGET PATH
1 2 1.2
2 4 1.2.4
4 9 1.2.4.9
Test en direct :http://www.sqlfiddle.com/#!1/13e6b/1
Similaire à ceci :Comment obtenir le parent donné à un enfant dans SQL SERVER 2005
Ceci est optimisé, coupez la récursivité au parent s'il trouve déjà la source spécifique.
Provenance =2
Cible =9
with recursive find_parent(source, target, recentness) as
(
select source, target, 0
from tbl
where target = 9
union all
select i.source, i.target, fp.recentness + 1
from tbl i
join find_parent fp on i.target = fp.source
-- despite the name, this target is another one's source
and i.target <> 2
)
,construct_path(source, target, recentness, path) as
(
select source, target, recentness, source || '.' || target
from find_parent
where recentness = (select max(recentness) from find_parent)
union
select dd.source, dd.target, dd.recentness, cp.path || '.' || dd.target
from find_parent dd
join construct_path cp on dd.recentness = cp.recentness - 1
)
select source, target, path
from construct_path
order by recentness desc
Sortie :
SOURCE TARGET PATH
2 4 2.4
4 9 2.4.9
Test en direct :http://www.sqlfiddle.com/#!1/13e6b/16