Oracle
 sql >> Database >  >> RDS >> Oracle

Relazione nidificata Oracle SQL in un unico livello

Non sono sicuro di aver compreso appieno la logica che stai cercando di implementare, ma qui c'è SQL che crea la tua tabella e duplica l'output di esempio. È stato testato su https://livesql.oracle.com

Per favore prendilo con le pinze perché se i tuoi dati possono avere righe o cicli duplicati o altro, ciò non è dimostrato nel tuo esempio, la query potrebbe richiedere una modifica.

Schema:

  1. Nella clausola "with", trasformiamo "ColumnA" e "ColumnB" in un'unica colonna e aggiungiamo col_src per preservare quale sia la nuova "ColumnAB".

  2. Quindi eseguiamo una query ricorsiva, collegandoci tramite una colonna D corrispondente e una colonna A/B che corrisponde alla colonna C precedente.

  3. Per abbinare l'ordine fornito, ordiniamo per:

    • il livello di ricorsione
    • colonna C
    • se la fonte era la colonna A o B
    • il valore della colonna A o 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"