Ik weet niet zeker of ik de logica die u probeert te implementeren volledig begrijp, maar hier is SQL die uw tabel maakt en uw voorbeelduitvoer dupliceert. Het is getest op https://livesql.oracle.com
Neem dit met een korreltje zout, want als uw gegevens dubbele rijen of cycli of wat dan ook bevatten, wat niet wordt aangetoond in uw voorbeeld, moet de zoekopdracht mogelijk worden gewijzigd.
Overzicht:
-
In de "with"-clausule draaien we "ColumnA" en "ColumnB" in een enkele kolom en voegen we col_src toe om te behouden welke de nieuwe "ColumnAB" is.
-
Vervolgens zoeken we recursief, waarbij we verbinden door een overeenkomende kolom D en een kolom A/B die overeenkomt met de vorige kolom C.
-
Om overeen te komen met de opgegeven volgorde, sorteren we op:
- het recursieniveau
- kolom C
- of de bron kolom A of B was
- de waarde van kolom A of 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"