我会这样做:
with t1 as (select 'AA' col1, 'BB' col2 from dual union all
select 'EE' col1, 'FF' col2 from dual union all
select 'YY' col1, 'ZZ' col2 from dual union all
select '11' col1, '00' col2 from dual),
t2 as (select 'AA' col1, 'BB' col2, 1 col3 from dual union all
select 'AA' col1, 'CC' col2, 2 col3 from dual union all
select 'CC' col1, 'BB' col2, 3 col3 from dual union all
select 'GG' col1, 'FF' col2, 4 col3 from dual union all
select 'GG' col1, 'HH' col2, 5 col3 from dual union all
select 'EE' col1, 'HH' col2, 6 col3 from dual union all
select 'XX' col1, 'YY' col2, 7 col3 from dual union all
select 'XX' col1, 'WW' col2, 8 col3 from dual union all
select 'YY' col1, 'RR' col2, 9 col3 from dual),
res as (select t1.col1,
t1.col2,
t2.col3,
case when t1.col1 = t2.col1 and t1.col2 = t2.col2 then 1
when t1.col2 = t2.col2 then 2
when t1.col1 = t2.col1 then 3
end join_level,
min (case when t1.col1 = t2.col1 and t1.col2 = t2.col2 then 1
when t1.col2 = t2.col2 then 2
when t1.col1 = t2.col1 then 3
end) over (partition by t1.col1, t1.col2) min_join_level
from t1
left outer join t2 on (t1.col1 = t2.col1 or t1.col2 = t2.col2))
select col1,
col2,
col3
from res
where join_level = min_join_level
or join_level is null;
COL1 COL2 COL3
---- ---- ----------
11 00
AA BB 1
EE FF 4
YY ZZ 9
即。首先进行连接(在这种情况下,t1 left outer join t2 on (t2.col1 = t1.col1 or t2.col2 = t1.col2) 包括 t1.col1 = t2.col1 and t1.col2 = t2.col2 所在的行),然后根据哪个连接条件优先过滤结果。
这里有一个稍微不同的选择,使用聚合而不是像上面的答案那样的分析函数:
with t1 as (select 'AA' col1, 'BB' col2 from dual union all
select 'EE' col1, 'FF' col2 from dual union all
select 'YY' col1, 'ZZ' col2 from dual union all
select '11' col1, '00' col2 from dual),
t2 as (select 'AA' col1, 'BB' col2, 1 col3 from dual union all
select 'AA' col1, 'CC' col2, 2 col3 from dual union all
select 'CC' col1, 'BB' col2, 3 col3 from dual union all
select 'GG' col1, 'FF' col2, 4 col3 from dual union all
select 'GG' col1, 'HH' col2, 5 col3 from dual union all
select 'EE' col1, 'HH' col2, 6 col3 from dual union all
select 'XX' col1, 'YY' col2, 7 col3 from dual union all
select 'XX' col1, 'WW' col2, 8 col3 from dual union all
select 'YY' col1, 'RR' col2, 9 col3 from dual)
select t1.col1,
t1.col2,
min(t2.col3) keep (dense_rank first order by case when t1.col1 = t2.col1 and t1.col2 = t2.col2 then 1
when t1.col2 = t2.col2 then 2
when t1.col1 = t2.col1 then 3
end) col3
from t1
left outer join t2 on (t1.col1 = t2.col1 or t1.col2 = t2.col2)
group by t1.col1,
t1.col2;
COL1 COL2 COL3
---- ---- ----------
11 00
AA BB 1
EE FF 4
YY ZZ 9
注意如果碰巧有不止一行满足最高优先级的可用连接条件,这些可能会返回不同的结果。第一个查询将返回具有(可能)不同的 col3 的每一行,而第二个查询将只返回一个具有最低可用 col3 值的行。
如果 T2 包含,您希望看到什么:
COL1 COL2 COL3
---- ---- ----------
AA BB 1
AA CC 2
CC BB 3
GG FF 4
GG HH 5
EE HH 6
XX YY 7
XX WW 8
YY RR 9
YY SS 10
第一个查询会给你:
COL1 COL2 COL3
---- ---- ----------
11 00
AA BB 1
EE FF 4
YY ZZ 10
YY ZZ 9
第二个查询会给你:
COL1 COL2 COL3
---- ---- ----------
11 00
AA BB 1
EE FF 4
YY ZZ 9