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

6-10 unionでfull joinを代用

SQLパズル

TBL_A
Key  Val
---  --------
100  トマト
200  きゅうり
400  たまねぎ

TBL_B
Key  Val
---  --------
100  トマト
300  ピーマン
400  にんじん

以下の出力形式で、TBL_AとTBL_Bの比較結果を出力する。
TBL_AとTBL_Bのプライマリキーは、Keyとする。

出力結果
KEY  状況
---  -----------------------------
100  TBL_AとTBL_BにありValが一致
200  TBL_Aにだけ存在
300  TBL_Bにだけ存在
400  TBL_AとTBL_BにありValが不一致

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


データ作成スクリプト

create table TBL_A(
Key number(3) primary key,
Val varchar2(8));

create table TBL_B(
Key number(3) primary key,
Val varchar2(8));

insert all
into TBL_A(Key,Val) values(100,'トマト')
into TBL_A(Key,Val) values(200,'きゅうり')
into TBL_A(Key,Val) values(400,'たまねぎ')
into TBL_B(Key,Val) values(100,'トマト')
into TBL_B(Key,Val) values(300,'ピーマン')
into TBL_B(Key,Val) values(400,'にんじん')
select 1 from dual;
commit;


SQL

--■■■full joinを使う方法■■■
select coalesce(a.Key,b.Key) as Key,
case when b.Key is null then 'TBL_Aにだけ存在'
     when a.Key is null then 'TBL_Bにだけ存在'
     when a.Val = b.Val then 'TBL_AとTBL_BにありValが一致'
     else 'TBL_AとTBL_BにありValが不一致' end as 状況
  from TBL_A a full join TBL_B b
    on a.Key = b.Key
order by Key;

--■■■full joinを使わない方法■■■
select Key,
case when max(BVal) is null then 'TBL_Aにだけ存在'
     when max(AVal) is null then 'TBL_Bにだけ存在'
     when max(AVal) = max(BVal) then 'TBL_AとTBL_BにありValが一致'
     else 'TBL_AとTBL_BにありValが不一致' end as 状況
from (select Key,Val as AVal,null as BVal from TBL_A
      union all
      select Key,null,Val from TBL_B)
group by Key
order by Key;


解説

完全外部結合による和集合と、
unionでの和集合は、
ベン図が一緒なので、
SQLを書き換えれることがあります。

3-27 full joinとunionの相互変換