Oracle SQL 嵌套关系成一级

Oracle SQL nested relationship into one level

ColumnA ColumnB  ColumnC ColumnD
A        B        C        E
D        C        F        E
C        H        I        E
C        W        S        E1

逻辑应该是当columnA/columnB在columnC有一条记录columnA/columnB在另一条相同columnD的记录时,会输出如下

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 以获得以下内容:

我不确定我是否完全理解您要实现的逻辑,但这里 SQL 创建了您的 table 并复制了您的示例输出。它在 https://livesql.oracle.com

上进行了测试

请对此持保留态度,因为如果您的数据可能有重复的行或循环或诸如此类的东西,而您的示例中并未证明这一点,则查询可能需要修改。

大纲:

  1. 在 "with" 子句中,我们将 "ColumnA" 和 "ColumnB" 转换为单个列,并添加 col_src 以保留新列"ColumnAB"是。

  2. 然后我们递归查询,通过匹配的列D和匹配上一列C的列A/B连接。

  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"