トップページに戻る
次のSQLパズルへ
前のSQLパズルへ
7-13 和集合を作成してmerge
SQLパズル
テーブルA
Code Name
---- ------
1 吉法師
2 日吉丸
3 竹千代
5 源頼朝
テーブルB
Code Name Nen
---- -------- ----
1 織田信長 1582
2 木下秀吉 1555
3 松平元康 1560
4 遮那王 1175
6 服部半蔵 1582
テーブルC
Code Name Nen
---- -------- ----
2 羽柴秀吉 1582
3 徳川家康 1600
4 源義経 1175
7 明智光秀 1600
テーブルAに、
テーブルBの全レコードと、
テーブルCの全レコードを追加更新(merge)する。
ただし、テーブルBとテーブルCに同じCodeが存在したら、
Nenの新しいほうを優先する、Nenが等しかったらテーブルCを優先する
テーブルA、テーブルB、テーブルCのプライマリキーは、Codeとする
Merge後のテーブルA
Code Name
---- --------
1 織田信長
2 羽柴秀吉
3 徳川家康
4 源義経
5 源頼朝
6 服部半蔵
7 明智光秀
データ作成スクリプト
create table テーブルA(
Code number(1),
Name char(8),
primary key(Code));
create table テーブルB(
Code number(1),
Name char(8),
Nen char(4),
primary key(Code));
create table テーブルC(
Code number(1),
Name char(8),
Nen char(4),
primary key(Code));
insert into テーブルA values(1,'吉法師');
insert into テーブルB values(1,'織田信長','1582');
insert into テーブルA values(2,'日吉丸');
insert into テーブルB values(2,'木下秀吉','1555');
insert into テーブルC values(2,'羽柴秀吉','1582');
insert into テーブルA values(3,'竹千代');
insert into テーブルB values(3,'松平元康','1560');
insert into テーブルC values(3,'徳川家康','1600');
insert into テーブルB values(4,'遮那王' ,'1175');
insert into テーブルC values(4,'源義経' ,'1175');
insert into テーブルA values(5,'源頼朝');
insert into テーブルB values(6,'服部半蔵','1582');
insert into テーブルC values(7,'明智光秀','1600');
commit;
SQL
--■■■グループ化する方法■■■
merge into テーブルA a
using (select Code,
max(Name) Keep(Dense_Rank First order by Nen desc,ID desc) as Name
from (select 1 as ID,Code,Name,Nen from テーブルB union all
select 2 as ID,Code,Name,Nen from テーブルC)
group by Code) d
on (a.Code=d.Code)
when matched then
update set a.Name=d.Name
when not matched then
insert(a.Code,a.Name) values(d.Code,d.Name);
--■■■exists述語を使う方法■■■
merge into テーブルA a
using (select b.Code,b.Name from テーブルB b
where not exists(select 1 from テーブルC c
where c.Code=b.Code
and c.Nen >= b.Nen)
union all
select c.Code,c.Name from テーブルC c
where not exists(select 1 from テーブルB b
where b.Code=c.Code
and c.Nen < b.Nen)) d
on (a.Code=d.Code)
when matched then
update set a.Name=d.Name
when not matched then
insert(a.Code,a.Name) values(d.Code,d.Name);
解説
exists述語を使う方法では、
mergeのusing句で、ブール代数の補元法則を使ってます。