Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Relacionamento aninhado Oracle SQL em um nível


Não tenho certeza se entendi completamente a lógica que você está tentando implementar, mas aqui está o SQL que cria sua tabela e duplica sua saída de exemplo. Foi testado em https://livesql.oracle.com

Por favor, leve isso com cautela, porque se seus dados podem ter linhas ou ciclos duplicados ou outros enfeites, isso não é demonstrado em seu exemplo, a consulta pode precisar de modificação.

Contorno:

  1. Na cláusula "with", giramos "ColumnA" e "ColumnB" em uma única coluna e adicionamos col_src para preservar qual é a nova "ColumnAB".

  2. Em seguida, consultamos recursivamente, conectando por uma coluna D correspondente e uma coluna A/B que corresponde à coluna anterior C.

  3. Para corresponder à ordenação fornecida, classificamos por:
    • o nível de recursão
    • coluna C
    • se a fonte era a coluna A ou B
    • o valor da coluna A ou B
create table mytable as
select 'A' "ColumnA",'B' "ColumnB",'C' "ColumnC",'E' "ColumnD" from dual
union select 'D' "ColumnA",'C' "ColumnB",'F' "ColumnC",'E' "ColumnD" from dual
union select 'C' "ColumnA",'H' "ColumnB",'I' "ColumnC",'E' "ColumnD" from dual
union select 'C' "ColumnA",'W' "ColumnB",'S' "ColumnC",'E1' "ColumnD" from dual
;

with temp as (
    select "ColumnA" as "ColumnAB", "ColumnC", "ColumnD", 'A' as col_src
    from mytable
    union all select "ColumnB", "ColumnC", "ColumnD", 'B' as col_src
    from mytable
)
select connect_by_root("ColumnAB") "ColumnV", "ColumnC" as "ColumnW" from temp
connect by prior "ColumnD" = "ColumnD" and prior "ColumnC" = "ColumnAB"
order by level,"ColumnC",col_src,  "ColumnAB"