トップページに戻る
次のSQLパズルへ
前のSQLパズルへ
3-2 別テーブル優先の抽出
SQLパズル
マスタテーブル
Col1 Col2 Col3
---- -------- ------------
1 吉法師 尾張のうつけ
2 日吉 日輪の子
3 竹千代 今川の人質
優先テーブル
Col1 Col2 Col3
---- -------- ------
1 織田信長 右大臣
3 徳川家康 内府
4 明智光秀 日向守
マスタテーブルのCol1,Col2,Col3を取得する
ただし、マスタテーブルのCol1に紐づくレコードが優先テーブルに存在すれば
優先テーブルのCol1,Col2,Col3を取得する。
マスタテーブル、優先テーブルのプライマリキーは、Col1とする。
出力結果
Col1 Col2 Col3
---- -------- ------
1 織田信長 右大臣
2 日吉 日輪の子
3 徳川家康 内府
データ作成スクリプト
create table マスタテーブル(
Col1 number,
Col2 varchar2(8),
Col3 varchar2(12),
primary key(Col1));
create table 優先テーブル(
Col1 number,
Col2 varchar2(8),
Col3 varchar2(12),
primary key(Col1));
insert into マスタテーブル values(1,'吉法師','尾張のうつけ');
insert into マスタテーブル values(2,'日吉','日輪の子');
insert into マスタテーブル values(3,'竹千代','今川の人質');
insert into 優先テーブル values(1,'織田信長','右大臣');
insert into 優先テーブル values(3,'徳川家康','内府');
insert into 優先テーブル values(4,'明智光秀','日向守');
commit;
SQL
--■■■nvl2関数で分岐させる方法■■■
select
a.Col1,
nvl2(b.Col1,b.Col2,a.Col2) as Col2,
nvl2(b.Col1,b.Col3,a.Col3) as Col3
from マスタテーブル a,優先テーブル b
where a.Col1=b.Col1(+)
order by Col1;
--■■■decode関数で分岐させる方法■■■
select
decode((select count(b.Col1) from 優先テーブル b where b.Col1=a.Col1),1,
(select b.Col1 from 優先テーブル b where b.Col1=a.Col1),Col1) as Col1,
decode((select count(b.Col1) from 優先テーブル b where b.Col1=a.Col1),1,
(select b.Col2 from 優先テーブル b where b.Col1=a.Col1),Col2) as Col2,
decode((select count(b.Col1) from 優先テーブル b where b.Col1=a.Col1),1,
(select b.Col3 from 優先テーブル b where b.Col1=a.Col1),Col3) as Col3
from マスタテーブル a
order by Col1;
--■■■case when existsで分岐させる方法■■■
select
case when exists(select 1 from 優先テーブル b where b.Col1=a.Col1)
then (select b.Col1 from 優先テーブル b where b.Col1=a.Col1)
else Col1 end as Col1,
case when exists(select 1 from 優先テーブル b where b.Col1=a.Col1)
then (select b.Col2 from 優先テーブル b where b.Col1=a.Col1)
else Col2 end as Col2,
case when exists(select 1 from 優先テーブル b where b.Col1=a.Col1)
then (select b.Col3 from 優先テーブル b where b.Col1=a.Col1)
else Col3 end as Col3
from マスタテーブル a
order by Col1;
--■■■unionを使用する方法■■■
select Col1,Col2,Col3 from マスタテーブル a
where not exists(select 1 from 優先テーブル b
where b.Col1=a.Col1)
union all select Col1,Col2,Col3 from 優先テーブル b
where exists(select 1 from マスタテーブル a
where b.Col1=a.Col1)
order by Col1;
解説
外部結合してnvl2関数で分岐させる方法や、
decode関数で分岐させる方法、case when existsで分岐させる方法がありますが、
unionを使用する方法もあります。
unionを使用する方法では、
マスタテーブルのCol1に紐づくレコードが優先テーブルに存在しなければ、最初のselect文が行を返し
マスタテーブルのCol1に紐づくレコードが優先テーブルに存在すれば、次のselect文が行を返す
クエリになっていて、
ブール代数の補元法則
A + not(A) = 1
を使用してます。