Joindre d'autres tables dans des requêtes oracle tree
-
02-07-2019 - |
Question
Étant donné un simple tableau (id, description) t1, tel que
id description
-- -----------
1 Alice
2 Bob
3 Carol
4 David
5 Erica
6 Fred
Et une table de relations parent-enfant t2, telle que
parent child
------ -----
1 2
1 3
4 5
5 6
Oracle propose un moyen de le parcourir sous forme d'arborescence avec des extensions de syntaxe personnalisées:
select parent, child, sys_connect_by_path(child, '/') as "path"
from t2
connect by prior parent = child
La syntaxe exacte n’est pas importante et j’ai probablement commis une erreur dans ce qui précède. le Ce qui est important est que ce qui précède produira quelque chose qui ressemble à
parent child path
------ ----- ----
1 2 /1/2
1 3 /1/3
4 5 /4/5
4 6 /4/5/6
5 6 /5/6
Ma question est la suivante: est-il possible de joindre une autre table dans sys_connect_by_path (), telle que la table t1 ci-dessus, pour produire quelque chose du type:
parent child path
------ ----- ----
1 2 /Alice/Bob
1 3 /Alice/Carol
... and so on...
La solution
Dans votre requête, remplacez T2 par une sous-requête joignant T1 et T2 et renvoyant la description du parent, de l'enfant et de l'enfant. Ensuite, dans la fonction sys_connect_by_path, référencez la description de l'enfant à partir de votre sous-requête.
Autres conseils
D'après l'idée de Mike McAllister, les éléments suivants utilisent un tableau dérivé pour obtenir le résultat souhaité:
select
T.PARENT
,T.CHILD
,sys_connect_by_path(T.CDESC, '/')
from
(
select
t2.parent as PARENT
,t2.child as CHILD
,t1.description as CDESC
from
t1, t2
where
t2.child = t1.id
) T
where
level > 1 and connect_by_isleaf = 1
connect by prior
T.CHILD = T.PARENT
Dans mon problème, tous les parents sont ancrés sous un "super parent". root, ce qui signifie que les chemins peuvent être entièrement décrits avec SYS_CONNECT_BY_PATH, évitant ainsi le recours à la technique de cagcowboy consistant à concaténer le parent avec le chemin.
SELECT parent, child, parents.description||sys_connect_by_path(childs.description, '/') AS "path"
FROM T1 parents, T1 childs, T2
WHERE T2.parent = parents.id
AND T2.child = childs.id
CONNECT BY PRIOR parent = child