Nie jestem pewien, czy w pełni rozumiem logikę, którą próbujesz zaimplementować, ale oto SQL, który tworzy twoją tabelę i duplikuje twoje przykładowe dane wyjściowe. Został przetestowany na https://livesql.oracle.com
Potraktuj to z przymrużeniem oka, ponieważ jeśli Twoje dane mogą zawierać zduplikowane wiersze lub cykle itp., czego nie pokazano w Twoim przykładzie, zapytanie może wymagać modyfikacji.
Zarys:
-
W klauzuli „with” przestawiamy „ColumnA” i „ColumnB” do jednej kolumny i dodajemy col_src, aby zachować nową kolumnę „ColumnAB”.
-
Następnie wykonujemy zapytania rekurencyjne, łącząc pasującą kolumnę D i kolumnę A/B, która pasuje do poprzedniej kolumny C.
-
Aby dopasować podaną kolejność, sortujemy według:
- poziom rekurencji
- kolumna C
- czy źródłem była kolumna A czy B
- wartość kolumny A lub 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"