トップページに戻る
次のSQLパズルへ
前のSQLパズルへ
10-198 existsとforallとunique
SQLパズル
CodeTable
Code Val
---- ---
AAAA 2
AAAA 4
AAAA 6
BBBB 1
BBBB 3
CCCC 2
CCCC 3
CCCC 4
DDDD 1
DDDD 2
Codeごとで、以下を満たすかのブール値を取得する。
exists_1 少なくとも1つのValが、2の倍数である
exists_2 少なくとも1つのValが、2の倍数でない
forall_1 全てのValが、2の倍数である
forall_2 全てのValが、2の倍数でない
unique_1 ただ1つのValが2の倍数である
unique_2 ただ1つのValが2の倍数でない
出力結果
Code exists_1 exists_2 forall_1 forall_2 unique_1 unique_2
---- -------- -------- -------- -------- -------- --------
AAAA 1 0 1 0 0 0
BBBB 0 1 0 1 0 0
CCCC 1 1 0 0 0 1
DDDD 1 1 0 0 1 1
データ作成スクリプト
create table CodeTable(Code,Val) as
select 'AAAA',2 from dual union
select 'AAAA',4 from dual union
select 'AAAA',6 from dual union
select 'BBBB',1 from dual union
select 'BBBB',3 from dual union
select 'CCCC',2 from dual union
select 'CCCC',3 from dual union
select 'CCCC',4 from dual union
select 'DDDD',1 from dual union
select 'DDDD',2 from dual;
SQL
select Code,
max(case when mod(Val,2) = 0 then 1 else 0 end) as exists_1,
max(case when mod(Val,2) = 0 then 0 else 1 end) as exists_2,
min(case when mod(Val,2) = 0 then 1 else 0 end) as forall_1,
min(case when mod(Val,2) = 0 then 0 else 1 end) as forall_2,
case sum(case when mod(Val,2) = 0 then 1 else 0 end) when 1 then 1 else 0 end as unique_1,
case sum(case when mod(Val,2) = 0 then 0 else 1 end) when 1 then 1 else 0 end as unique_2
from CodeTable
group by Code
order by Code;
解説
uniqueは、sumで数えるといいでしょう。
case式が2つある時は、単純case式と検索case式を混ぜると分かりやすいと思います。
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
存在肯定命題 (少なくとも1つのXが、2の倍数である)
存在否定命題 (少なくとも1つのXが、2の倍数でない)
全称肯定命題 (全てのXが、2の倍数である)
全称否定命題 (全てのXが、2の倍数でない)
は、それぞれ
存在肯定命題 max(case when mod(Val,2) = 0 then 1 else 0 end) (少なくとも1つのXが、2の倍数である)
存在否定命題 max(case when mod(Val,2) = 0 then 0 else 1 end) (少なくとも1つのXが、2の倍数でない)
全称肯定命題 min(case when mod(Val,2) = 0 then 1 else 0 end) (全てのXが、2の倍数である)
全称否定命題 min(case when mod(Val,2) = 0 then 0 else 1 end) (全てのXが、2の倍数でない)
となります。
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
変換公式をメモしておきましょう。
全称 → min
存在 → max
肯定 → (case when 条件 then 1 else 0 end)
否定 → (case when 条件 then 0 else 1 end)
まとめると
全称肯定命題なら min(case when 条件 then 1 else 0 end) = 1
全称否定命題なら min(case when 条件 then 0 else 1 end) = 1
存在肯定命題なら max(case when 条件 then 1 else 0 end) = 1
存在否定命題なら max(case when 条件 then 0 else 1 end) = 1
真なら1、偽なら0にしておくことにより、ブール値としても使えます。