トップページに戻る
次のSQLパズルへ
前のSQLパズルへ
4-5 case式による他分岐
SQLパズル
テーブルA
Y Z
- -
1 1
1 2
1 3
2 4
2 5
2 6
3 7
3 8
3 9
テーブルB
Z val1
- -----------
1 テーブルB1
3 テーブルB3
5 テーブルB5
テーブルC
Z val1
- -----------
3 テーブルC3
5 テーブルC5
テーブルD
Z val1
- -----------
8 テーブルD8
9 テーブルD9
テーブルAがあり、Y,Zで構成されている。
列Yの値が
1の時、テーブルBと、列Zの値をキーとして外部結合する。
2の時、テーブルCと、列Zの値をキーとして外部結合する。
3の時、テーブルDと、列Zの値をキーとして外部結合する。
出力結果
Y Z VAL1
- - -----------
1 1 テーブルB1
1 2 null
1 3 テーブルB3
2 4 null
2 5 テーブルC5
2 6 null
3 7 null
3 8 テーブルD8
3 9 テーブルD9
こちらを参考にさせていただきました
データ作成スクリプト
create table テーブルA(
Y number(1),
Z number(1));
create table テーブルB(
Z number(1),
val1 varchar2(12));
create table テーブルC as select * from テーブルB;
create table テーブルD as select * from テーブルB;
insert into テーブルA(Y,Z) values(1,1);
insert into テーブルA(Y,Z) values(1,2);
insert into テーブルA(Y,Z) values(1,3);
insert into テーブルB(Z,val1) values(1,'テーブルB1');
insert into テーブルB(Z,val1) values(3,'テーブルB3');
insert into テーブルB(Z,val1) values(5,'テーブルB5');
insert into テーブルA(Y,Z) values(2,4);
insert into テーブルA(Y,Z) values(2,5);
insert into テーブルA(Y,Z) values(2,6);
insert into テーブルC(Z,val1) values(3,'テーブルC3');
insert into テーブルC(Z,val1) values(5,'テーブルC5');
insert into テーブルA(Y,Z) values(3,7);
insert into テーブルA(Y,Z) values(3,8);
insert into テーブルA(Y,Z) values(3,9);
insert into テーブルD(Z,val1) values(8,'テーブルD8');
insert into テーブルD(Z,val1) values(9,'テーブルD9');
commit;
SQL
--■■■case式による他分岐を使用する方法■■■
select Y,Z,
case Y
when 1 then (select b.val1 from テーブルB b where b.Z=a.Z)
when 2 then (select b.val1 from テーブルC b where b.Z=a.Z)
when 3 then (select b.val1 from テーブルD b where b.Z=a.Z) end as val1
from テーブルA a
order by Y,Z;
--■■■decode関数による他分岐を使用する方法■■■
select Y,Z,
decode(Y,1,(select b.val1 from テーブルB b where b.Z=a.Z),
2,(select b.val1 from テーブルC b where b.Z=a.Z),
3,(select b.val1 from テーブルD b where b.Z=a.Z)) as val1
from テーブルA a
order by Y,Z;
--■■■unionで和集合を作成する方法■■■
select a.Y,a.Z,b.val1 from テーブルA a,テーブルB b
where a.Z=b.Z(+)
and a.Y=1
union all select a.Y,a.Z,b.val1 from テーブルA a,テーブルC b
where a.Z=b.Z(+)
and a.Y=2
union all select a.Y,a.Z,b.val1 from テーブルA a,テーブルD b
where a.Z=b.Z(+)
and a.Y=3
union all select Y,Z,null
from テーブルA a
where Y not in(1,2,3) or Y is null
order by 1,2;
--■■■外部結合とcoalesce関数を使用する方法■■■
select a.Y,a.Z,coalesce(b.val1,c.val1,d.val1) as val1
from テーブルA a
Left join テーブルB b ON a.Y=1 AND b.Z=a.Z
Left join テーブルC c ON a.Y=2 AND c.Z=a.Z
Left join テーブルD d ON a.Y=3 AND d.Z=a.Z
order by a.Y,a.Z;
解説
case式による他分岐、decode関数による他分岐、
unionで和集合を作成する方法、外部結合とcoalesce関数を使用する方法などがありますが、
case式による他分岐が、最も可読性の高いSQLになると思います。
ただし、スカラー問い合わせで2行以上の行を返すとエラーとなるため
case式、およびdecode関数による他分岐は、
エンティティ間が、1対1もしくは、多対1の場合にしか使えません。
他の方法は1対1、多対1、1対多、多対多いずれの場合でも使えます。
switch制御
switch文を扱おう