Я не уверен, полностью ли я понимаю логику c, которую вы пытаетесь реализовать, но вот SQL, которая создает вашу таблицу и дублирует ваш пример вывода. Он был протестирован на https://livesql.oracle.com
Пожалуйста, примите это с крошкой соли, потому что, если ваши данные могут иметь повторяющиеся строки или циклы или еще много чего, что не продемонстрировано в вашем примере, запрос может потребоваться модификация.
Структура:
В предложении «with» мы объединяем «ColumnA» и «ColumnB» в один столбец и добавляем col_sr c чтобы сохранить, какой из них новый "ColumnAB".
Затем мы рекурсивно запрашиваем, соединяя соответствующий столбец D и столбец A / B, который соответствует предыдущему столбцу C.
Чтобы соответствовать предоставленному порядку, мы сортируем по:
- уровень рекурсии
- столбец C
- был ли источником столбец A или B
- значение столбца A или 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"