问题
ColumnA ColumnB ColumnC ColumnD
A B C E
D C F E
C H I E
C W S E1
The logic should be when columnA/columnB has a record in columnC which is columnA/columnB in another record with the same columnD, it will be output as the following
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
How can I write a sql to get the following:
回答1:
I'm not sure if I fully understand the logic you are trying to implement, but here is SQL that creates your table and duplicates your example output. It was tested on https://livesql.oracle.com
Please take this with a grain of salt because if your data may have duplicate rows or cycles or whatnot, that is not demonstrated in your example, the query might need modification.
Outline:
In the "with" clause, we pivot "ColumnA" and "ColumnB" into a single column, and add col_src to preserve which one the new "ColumnAB" is.
Then we recursively query, connecting by a matching column D and a column A/B that matches the previous column C.
To match the ordering provided, we sort by:
- the recursion level
- column C
- whether the source was column A or B
- the value of the column A or 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"
来源:https://stackoverflow.com/questions/60965028/oracle-sql-nested-relationship-into-one-level