Juntando outras tabelas em consultas de árvores oracle
-
02-07-2019 - |
Pergunta
Dada uma simples (id, description) da tabela t1, como
id description
-- -----------
1 Alice
2 Bob
3 Carol
4 David
5 Erica
6 Fred
E um pai-filho tabela de relacionamento t2, como
parent child
------ -----
1 2
1 3
4 5
5 6
A Oracle oferece uma maneira de atravessar isso como uma árvore com algumas extensões de sintaxe de costume:
select parent, child, sys_connect_by_path(child, '/') as "path"
from t2
connect by prior parent = child
A sintaxe exata não é importante, e eu provavelmente cometeu um erro no exemplo acima. o importante é que o acima irá produzir algo que se parece com
parent child path
------ ----- ----
1 2 /1/2
1 3 /1/3
4 5 /4/5
4 6 /4/5/6
5 6 /5/6
A minha pergunta é esta: é possível para se juntar a uma outra tabela dentro da sys_connect_by_path (), como a tabela t1 acima, para produzir algo como:
parent child path
------ ----- ----
1 2 /Alice/Bob
1 3 /Alice/Carol
... and so on...
Solução
Em sua consulta, substituir T2 com uma subconsulta que une T1 e T2, e retorna pais, filhos e descrição criança. Em seguida, na função sys_connect_by_path, referência a descrição criança do seu subconsulta.
Outras dicas
Com base na ideia de Mike McAllister, a seguir usa uma tabela derivada de alcançar o resultado desejado:
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
No meu problema, todos os pais são ancorados em um "super-pai" root, o que significa que os caminhos podem ser completamente descritos com SYS_CONNECT_BY_PATH, eliminando assim a necessidade de técnica de cagcowboy de concatenar o pai com o caminho.
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