トップページに戻る
次のSQLパズルへ
前のSQLパズルへ
8-2 case式でis not falseを模倣
SQLパズル
以下のSQLをOracle9iのSQLで記述する(?はバインド変数)
select UserID,EntryDay,age from Table_Name
where
(
UserID = ?
and EntryDay = ?
and age >= ?
and age < ?
) is not false
order by UserID;
データ作成スクリプト
create table Table_Name(
UserID number(1),
EntryDay Date,
age number(3));
insert into Table_Name values(1,to_date('20050101','yyyymmdd'),20);
insert into Table_Name values(2,to_date('20050201','yyyymmdd'),25);
insert into Table_Name values(3,to_date('20050301','yyyymmdd'),30);
insert into Table_Name values(4,to_date('20050401','yyyymmdd'),35);
insert into Table_Name values(5,to_date('20050501','yyyymmdd'),40);
insert into Table_Name values(null,null,45);
commit;
SQL
--■■■case式を使用■■■
select UserID,EntryDay,age from Table_Name
where case when not (
UserID = ?
and EntryDay = ?
and age >= ?
and age < ?
) then 1 else 0 end =0
order by UserID;
--■■■スカラー問い合わせを使用■■■
select UserID,EntryDay,age from Table_Name
where (select count(*) from dual where not (
UserID = ?
and EntryDay = ?
and age >= ?
and age < ?
)) =0
order by UserID;
--■■■unknownとの論理積を調べる方法(Oracleだとエラーになるようです)■■■
--select UserID,EntryDay,age from Table_Name
-- where ((UserID = ?
-- and EntryDay = ?
-- and age >= ?
-- and age < ?) and null = null) is null
--order by UserID;
実行例
select UserID,EntryDay,age from Table_Name
where case when not (
UserID = null
and EntryDay = null
and age >= null
and age < null
) then 1 else 0 end =0
order by UserID;
select UserID,EntryDay,age from Table_Name
where case when not (
UserID = null
and EntryDay = to_date('20050401','yyyymmdd')
and age >= null
and age < null
) then 1 else 0 end =0
order by UserID;
select UserID,EntryDay,age from Table_Name
where case when not (
UserID = null
and EntryDay = null
and age >= 20
and age < 30
) then 1 else 0 end =0
order by UserID;
select UserID,EntryDay,age from Table_Name
where (select count(*) from dual where not (
UserID = null
and EntryDay = null
and age >= 20
and age < 30
)) =0
order by UserID;
解説
case式や、スカラー問い合わせで、
is not falseを模倣できます。
検索対象のカラムがNULLだと、検索条件を指定しても、
その行はヒットする点に注意する必要があります。
■■■■■■■■■■■■■■■■■■■■■■■■■■■■
(条件A) is not false ⇔ (not(条件A)) is not true
という論理を使ってます
(条件A) is not false ⇔ (not(条件A)) is not true の証明
not(true) = false
not(unknown) = unknown
not(false) = true
より
条件Aがtrue ⇒ not(条件A)がfalse
条件Aがunknown ⇒ not(条件A)がunknown
条件Aがfalse ⇒ not(条件A)がtrue
条件Aがtrue、条件Aがfalse、条件Aがunknownは、
全ての場合を網羅している。(和集合が全体集合)
(not 条件X)がfalse、(not 条件X)がtrue、(not 条件X)がunknownは、
どの2つも両立しない(どの2つの共通集合も空集合)
よって、転換法より、逆も真となるので、
条件Aがtrue ⇔ not(条件A)がfalse
条件Aがunknown ⇔ not(条件A)がunknown
条件Aがfalse ⇔ not(条件A)がtrue
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
条件A is not false
⇔ (条件A が true) または (条件A が unknown)
⇔ ((not 条件A)がfalse) または ((not 条件A)がunknown)
not 条件Aを、条件B
とおいて
⇔ ((not 条件A)がfalse) または ((not 条件A)がunknown)
⇔ (条件Bがfalse) または (条件Bがunknown)
⇔ 条件B is not true
よって
条件A is not false ⇔ (not 条件A) is not true
そして、not(条件A)
を、検索case式のwhen句で使ってます。
2-2-11 case式とLNNVL述語
10-155 is not trueとis not falseを模倣
NULL、Unknown、3値論理
3値論理 ―― 神のいない論理
3値論理とNULL:CodeZine
BOOLEAN型の資料
証明 - Wikipedia
対偶証明法と背理法
【第77回】転換法