トップページに戻る    次のSQLパズルへ    前のSQLパズルへ

10-216 nullの列を追加して完全外部結合を代用

SQLパズル

TableA       TableB
Key  Col1    Key  Col1
---  ----    ---  ----
A    1243    A    1234
B    2345    C    6534
C    3456    E    7654

TableAのprimary keyは、Keyで
TableBのprimary keyも、Keyです。

primary key同士をマッチングのキーとして、
TableAのみに存在するデータは、区分=1
TableBのみに存在するデータは、区分=2
TableAとTableBの存在するが、Col1の値が異なるデータは、区分=3

として、下記のように出力する。

出力結果
区分  KEY_A  COLA  KEY_B  COLB
----  -----  ----  -----  ----
   1  B      2345  null   null
   2  null   null  E      7654
   3  C      3456  C      6534

こちらを参考にさせていただきました


データ作成スクリプト

create table TableA(key primary key,Col1) as
select 'A',1234 from dual union
select 'B',2345 from dual union
select 'C',3456 from dual;

create table TableB(key primary key,Col1) as
select 'A',1234 from dual union
select 'C',6534 from dual union
select 'E',7654 from dual;


SQL

Col key_a for a10
Col key_b for a10

--■■■full joinを使わない方法■■■
select decode(count(*),1,nvl2(max(ColA),1,2),3) as 区分,
nvl2(max(ColA),Key,null) as key_a , max(ColA) as ColA,
nvl2(max(ColB),Key,null) as key_b , max(ColB) as ColB
from (select key,Col1 as ColA,to_number(null) as ColB from TableA
      union all
      select key,to_number(null),Col1 from TableB)
group by key
having count(*) = 1
    or max(ColA) != max(ColB)
order by 区分;

--■■■full joinを使う方法■■■
select case when Least(a.Key,b.Key) is not null then 3
            else nvl2(a.Key,1,2) end as 区分,
a.Key as key_a , a.Col1 as ColA,
b.Key as key_b , b.Col1 as ColB
  from TableA a full join TableB b
    on (a.Key = b.Key)
 where case when a.Col1 = b.Col1 then 1 else 0 end = 0
order by 区分;


解説

ベン図を脳内でイメージすると分かりやすいでしょう。