トップページに戻る
次のSQLパズルへ
前のSQLパズルへ
9-28 等しい集合が存在する、集合を求める
SQLパズル
PartsTable1 PartsTable2
ID Val ID Val
--- --- --- ---
AAA 10 AAA 10
AAA 20 AAA 30
BBB 10 BBB 10
BBB 40 BBB 40
CCC 40 CCC 30
CCC 50 DDD 60
DDD 60 DDD 70
EEE 80 EEE 80
FFF 10 FFF 10
FFF 70 FFF 30
GGG 20
PartsTable1とPartsTable2の、IDごとの集合で
互いに等しい集合を出力する
PartsTable1とPartsTable2に、
重複行は存在しないものとする
出力結果
ID Val
--- ---
BBB 10
BBB 40
EEE 80
SQLパズル(日本語版)のパズル26 [等集合の発見] を参考にさせていただきました
SQLパズル 第2版のパズル27 [等しい集合を見つける] を参考にさせていただきました
データ作成スクリプト
create table PartsTable1 as
select 'AAA' as ID,10 as Val from dual
union select 'AAA',20 from dual
union select 'BBB',10 from dual
union select 'BBB',40 from dual
union select 'CCC',40 from dual
union select 'CCC',50 from dual
union select 'DDD',60 from dual
union select 'EEE',80 from dual
union select 'FFF',10 from dual
union select 'FFF',70 from dual
union select 'GGG',20 from dual;
create table PartsTable2 as
select 'AAA' as ID,10 as Val from dual
union select 'AAA',30 from dual
union select 'BBB',10 from dual
union select 'BBB',40 from dual
union select 'CCC',30 from dual
union select 'DDD',60 from dual
union select 'DDD',70 from dual
union select 'EEE',80 from dual
union select 'FFF',10 from dual
union select 'FFF',30 from dual;
SQL
--■■■分析関数を使う方法1■■■
select ID,Val
from (select a.ID,a.Val,a.結合可能数,count(*) over(partition by a.ID) as 結合数
from (select ID,Val,count(*) over(partition by ID) as 結合可能数
from PartsTable1) a,
(select ID,Val,count(*) over(partition by ID) as 結合可能数
from PartsTable2) b
where a.ID = b.ID
and a.Val = b.Val
and a.結合可能数 = b.結合可能数)
where 結合可能数 = 結合数;
--■■■分析関数を使う方法2■■■
select ID,Val
from PartsTable1 a
where not exists(select b.ID,b.Val,count(*) over()
from PartsTable1 b
where b.ID = a.ID
minus
select b.ID,b.Val,count(*) over()
from PartsTable2 b
where b.ID = a.ID);
--■■■分析関数を使わない方法1■■■
select ID,Val
from PartsTable1 a
where not exists(select b.ID,b.Val
from PartsTable1 b
where b.ID = a.ID
minus
select b.ID,b.Val
from PartsTable2 b
where b.ID = a.ID)
and not exists(select b.ID,b.Val
from PartsTable2 b
where b.ID = a.ID
minus
select b.ID,b.Val
from PartsTable1 b
where b.ID = a.ID);
--■■■分析関数を使わない方法2■■■
select ID,Val
from PartsTable1 a
where not exists(select b.ID,b.Val
from PartsTable1 b
where b.ID = a.ID
minus
select b.ID,b.Val
from PartsTable2 b
where b.ID = a.ID)
and (select count(*) from PartsTable1 b
where b.ID = a.ID) =
(select count(*) from PartsTable2 b
where b.ID = a.ID);
解説
IDの等しい集合を求めて、集合演算を行ってます