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