Je ne sais pas si je comprends parfaitement la logique que vous essayez de mettre en œuvre, mais voici SQL qui crée votre table et duplique votre exemple de sortie. Il a été testé sur https://livesql.oracle.com
Veuillez prendre cela avec un grain de sel, car si vos données peuvent avoir des lignes ou des cycles en double ou quoi que ce soit d'autre, cela n'est pas démontré dans votre exemple, la requête peut nécessiter une modification.
Contour :
-
Dans la clause "with", nous faisons pivoter "ColumnA" et "ColumnB" dans une seule colonne, et ajoutons col_src pour conserver laquelle est la nouvelle "ColumnAB".
-
Ensuite, nous interrogeons de manière récursive, en nous connectant par une colonne correspondante D et une colonne A/B qui correspond à la colonne précédente C.
-
Pour correspondre à l'ordre fourni, nous trions par :
- le niveau de récursivité
- colonne C
- si la source était la colonne A ou B
- la valeur de la colonne 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"