Вы можете получить то, что (я думаю), что вы хотите с внешними я присоединяется:
-- CTE for sample data, including row_num to maintain display order
with mydata (row_num, Num_A, Num_B, Num_C, Reg_1, Reg_2) as (
select 1, 94000, 95000, 97000, 'AAA', 'CCC' from dual
union all select 2, 97000, 94000, 95000, 'BBB', 'DDD' from dual
union all select 3, 95000, 94000, 92000, 'EEE', 'AAA' from dual
union all select 4, 91000, 93000, 99000, 'AAA', 'DDD' from dual
)
-- actual query
select m.*,
case when m1.num_a is not null then m.num_a || m1.num_a end as comm_1,
case when m2.num_a is not null then m.num_a || m2.num_a end as comm_2,
case when m3.num_a is not null then m.num_a || m3.num_a end as comm_3
from mydata m
left join mydata m1 on m1.num_a = m.num_b
left join mydata m2 on m2.num_a = m.num_c
left join mydata m3 on m3.num_a = m.num_b and (m3.reg_1 = m.reg_2 or m3.reg_2 = m.reg_1)
order by m.row_num;
ROW_NUM NUM_A NUM_B NUM_C REG REG COMM_1 COMM_2 COMM_3
---------- ---------- ---------- ---------- --- --- ---------- ---------- ----------
1 94000 95000 97000 AAA CCC 9400095000 9400097000 9400095000
2 97000 94000 95000 BBB DDD 9700094000 9700095000
3 95000 94000 92000 EEE AAA 9500094000 9500094000
4 91000 93000 99000 AAA DDD
(я оставил в row_num
только для того, чтобы сохранить порядок отображения, он не используется иначе; я предполагаю, что на самом деле это не столбец в вашей таблице.)
Значение comm_1
основано на левом соединении с другой строкой, в которой num_a
соответствует num_b
.
этой строки.
Значение comm_2
основано на левом соединении с другой строкой, у которой num_a
соответствует этой строке num_c
.
Значение comm_3
совпадает с comm_1
, но оно также должно совпадать с reg_1
с reg_2
в другой строке или наоборот. Но это вычисляет значение строки 3 как 9500094000, а не как 94009500, показанный в вопросе - хотя не ясно, что верно.
Это также получит повторяющиеся строки, если для любого из внешних объединений будет найдено более одного совпадения; это не относится к вашим образцам данных, но есть что-то, на что следует обратить внимание Я понятия не имею, как бы вы хотели справиться с этим, если это может произойти.
Вы также можете сделать это с одним внешним соединением и большим количеством логики / агрегации в выражениях столбца:
select m.row_num, m.num_a, m.num_b, m.num_c, m.reg_1, m.reg_2,
max(case when m1.num_a = m.num_b then m.num_a || m1.num_a end) as comm_1,
max(case when m1.num_a = m.num_c then m.num_a || m1.num_a end) as comm_2,
max(case when m1.num_a = m.num_b and (m1.reg_1 = m.reg_2 or m1.reg_2 = m.reg_1)
then m.num_a || m1.num_a end) as comm_3
from mydata m
left join mydata m1 on (m1.num_a = m.num_b) or (m1.num_a = m.num_c)
group by m.row_num, m.num_a, m.num_b, m.num_c, m.reg_1, m.reg_2
order by m.row_num;
ROW_NUM NUM_A NUM_B NUM_C REG REG COMM_1 COMM_2 COMM_3
---------- ---------- ---------- ---------- --- --- ---------- ---------- ----------
1 94000 95000 97000 AAA CCC 9400095000 9400097000 9400095000
2 97000 94000 95000 BBB DDD 9700094000 9700095000
3 95000 94000 92000 EEE AAA 9500094000 9500094000
4 91000 93000 99000 AAA DDD