トップページに戻る
次のSQLパズルへ
前のSQLパズルへ
9-46 順序無視で重複チェック(各値の重複あり)
SQLパズル
StringTable
ID ColA ColB ColC
-- ---- ---- ----
1 A A A ←出力対象
2 A A B
3 A A C
4 A B A
5 A B B
6 A B C ←出力対象
7 A C A
8 A C C
9 B A A
10 B A B
11 B B A
12 B B B ←出力対象
13 B B C
14 B C B
15 B C C
16 C A A
17 C A C
18 C B B
ColAとColBとColCの順序を無視した組み合わせで、
重複が存在しないレコードを出力する
データ作成スクリプト
create table StringTable(
ID number(2) not null,
ColA char(1) not null,
ColB char(1) not null,
ColC char(1) not null);
insert into StringTable values( 1,'A','A','A');
insert into StringTable values( 2,'A','A','B');
insert into StringTable values( 3,'A','A','C');
insert into StringTable values( 4,'A','B','A');
insert into StringTable values( 5,'A','B','B');
insert into StringTable values( 6,'A','B','C');
insert into StringTable values( 7,'A','C','A');
insert into StringTable values( 8,'A','C','C');
insert into StringTable values( 9,'B','A','A');
insert into StringTable values(10,'B','A','B');
insert into StringTable values(11,'B','B','A');
insert into StringTable values(12,'B','B','B');
insert into StringTable values(13,'B','B','C');
insert into StringTable values(14,'B','C','B');
insert into StringTable values(15,'B','C','C');
insert into StringTable values(16,'C','A','A');
insert into StringTable values(17,'C','A','C');
insert into StringTable values(18,'C','B','B');
insert into StringTable values(19,'C','B','C');
commit;
SQL
with WorkView as (
select ID,ColA,ColB,ColC,
decode(ColA,ColB,1,0)+decode(ColA,ColC,1,0) as ColAC,
decode(ColB,ColA,1,0)+decode(ColB,ColC,1,0) as ColBC,
decode(ColC,ColA,1,0)+decode(ColC,ColB,1,0) as ColCC
from StringTable)
select ID,ColA,ColB,ColC
from WorkView a
where not exists(select 1 from WorkView b
where a.RowID != b.RowID
and (a.ColA,a.ColAC) in((b.ColA,b.ColAC),(b.ColB,b.ColBC),(b.ColC,b.ColCC))
and (a.ColB,a.ColBC) in((b.ColA,b.ColAC),(b.ColB,b.ColBC),(b.ColC,b.ColCC))
and (a.ColC,a.ColCC) in((b.ColA,b.ColAC),(b.ColB,b.ColBC),(b.ColC,b.ColCC))
and (b.ColA,b.ColAC) in((a.ColA,a.ColAC),(a.ColB,a.ColBC),(a.ColC,a.ColCC))
and (b.ColB,b.ColBC) in((a.ColA,a.ColAC),(a.ColB,a.ColBC),(a.ColC,a.ColCC))
and (b.ColC,b.ColCC) in((a.ColA,a.ColAC),(a.ColB,a.ColBC),(a.ColC,a.ColCC)));
解説
各値の個数を求めてから、
包含関係を調べてます
数学の集合理論の、
集合Aが集合Bの部分集合で、かつ
集合Bが集合Aの部分集合ならば、
集合Aと集合Bは等しい
(A=B ⇔ A⊂B かつ B⊂A)
を使ってます
各値に重複が存在しない場合は、
7-41 順序無視の重複チェック(各値の重複なし)
の方法でいいです