Oracle SQL вложенные отношения в один уровень - PullRequest
0 голосов
/ 01 апреля 2020
ColumnA ColumnB  ColumnC ColumnD
A        B        C        E
D        C        F        E
C        H        I        E
C        W        S        E1

Лог c должен быть, когда для columnA / columnB есть запись в столбце C, которая является columnA / columnB в другой записи с таким же столбцом D, она будет выводиться как следующая

ColumnV  ColumnW
A          C
B          C
D          F
C          F
C          I
H          I
C          S
W          S
A          F
B          F
A          I
B          I 

Как мне написать sql, чтобы получить следующее:

1 Ответ

0 голосов
/ 04 апреля 2020

Я не уверен, полностью ли я понимаю логику c, которую вы пытаетесь реализовать, но вот SQL, которая создает вашу таблицу и дублирует ваш пример вывода. Он был протестирован на https://livesql.oracle.com

Пожалуйста, примите это с крошкой соли, потому что, если ваши данные могут иметь повторяющиеся строки или циклы или еще много чего, что не продемонстрировано в вашем примере, запрос может потребоваться модификация.

Структура:

  1. В предложении «with» мы объединяем «ColumnA» и «ColumnB» в один столбец и добавляем col_sr c чтобы сохранить, какой из них новый "ColumnAB".

  2. Затем мы рекурсивно запрашиваем, соединяя соответствующий столбец D и столбец A / B, который соответствует предыдущему столбцу C.

  3. Чтобы соответствовать предоставленному порядку, мы сортируем по:

    • уровень рекурсии
    • столбец 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"
...