トップページに戻る
次のSQLパズルへ
前のSQLパズルへ
3-38 Outer Union (外和集合演算)
SQLパズル
NameTable AgeTable
ID seq Name ID seq Age
-- --- -------- -- --- ---
1 1 Oda 1 1 49
1 2 Aketi 1 3 20
2 1 Tokugawa 2 1 70
2 2 Honda 2 4 30
2 3 Sakai
3 1 Toyotomi
下記のOuter Union (外和集合演算)を模倣する。
(2008/9/16現在、Outer Unionは、Oracle11gですら使えません)
select ID,Seq,Name from NameTable
Outer Union
select ID,Seq,Age from NameTable
出力結果
ID SEQ Name Age
-- --- -------- ----
1 1 Oda 49
1 2 Aketi null
1 3 null 20
2 1 Tokugawa 70
2 2 Honda null
2 3 Sakai null
2 4 null 30
3 1 Toyotomi null
データ作成スクリプト
create table NameTable(
ID number(2),
seq number(2),
Name varchar2(8),
primary key (ID,Seq));
create table AgeTable(
ID number(2),
seq number(2),
Age number(2),
primary key (ID,Seq));
insert all
into NameTable values(1,1,'Oda')
into AgeTable values(1,1,49)
into NameTable values(1,2,'Aketi')
into AgeTable values(1,3,20)
into NameTable values(2,1,'Tokugawa')
into AgeTable values(2,1,70)
into NameTable values(2,2,'Honda')
into NameTable values(2,3,'Sakai')
into AgeTable values(2,4,30)
into NameTable values(3,1,'Toyotomi')
select 1 from dual;
commit;
SQL
--■■■union allを使う方法■■■
select ID,seq,max(Name) as Name,max(age) as age
from (select ID,seq,Name ,to_number(null) as age from NameTable union all
select ID,seq,to_char(null),Age from AgeTable)
group by ID,seq
order by ID,seq;
--■■■完全外部結合を使う方法1■■■
select nvl(a.ID,b.ID) as ID,nvl(a.seq,b.seq) as seq,a.Name,b.Age
from NameTable a full join AgeTable b
on a.ID = b.ID
and a.seq = b.seq
order by ID,seq;
--■■■完全外部結合を使う方法2■■■
select ID,seq,a.Name,b.Age
from NameTable a natural full join AgeTable b
order by ID,seq;
解説
完全外部結合を使う方法1がオススメです。
完全外部結合を使う方法2は、同じ名前の列がなかったらクロスジョインになりますし、
仕様変更にも弱いでしょう。
データベース概説(第4回)(PDF)