トップページに戻る    次のSQLパズルへ    前のSQLパズルへ

10-176 範囲にnullを含むかのチェック

SQLパズル

ymdTable
key  ymd
---  --------
  1  2007/9/1
  2  null
  3  2007/9/3
  4  2007/9/4
  5  2007/9/5

keyの開始と終了を指定して、
keyの開始と終了の間の、ymdの最大値を求める。
ただし、keyの開始と終了の間のymdにnullがあったら、
ymdの最大値はnullとする。

出力結果 (keyの開始が1、keyの終了が3の場合)
ymd
----
null

出力結果 (keyの開始が3、keyの終了が5の場合)
ymd
--------
2007/9/5


データ作成スクリプト

create table ymdTable(
key number(1),
ymd date);

insert into ymdTable values(1,to_date('2007/9/1','fmyyyy/mm/dd'));
insert into ymdTable values(2,null);
insert into ymdTable values(3,to_date('2007/9/3','fmyyyy/mm/dd'));
insert into ymdTable values(4,to_date('2007/9/4','fmyyyy/mm/dd'));
insert into ymdTable values(5,to_date('2007/9/5','fmyyyy/mm/dd'));
commit;


SQL

--■■■全てnullでないという全称命題の真偽を調べる方法■■■
select case when min(nvl2(ymd,1,0)) = 1
            then max(ymd) end as ymd
  from ymdTable
 where key between 1 and 3;

select case when min(nvl2(ymd,1,0)) = 1
            then max(ymd) end as ymd
  from ymdTable
 where key between 3 and 5;

--■■■count(*)とcount(ymd)を比較する方法■■■
select decode(count(*),count(ymd),max(ymd)) as ymd
  from ymdTable
 where key between 1 and 3;

select decode(count(*),count(ymd),max(ymd)) as ymd
  from ymdTable
 where key between 3 and 5;

--■■■Keepを使う方法■■■
select max(ymd) Keep(Dense_Rank Last order by ymd) as ymd
  from ymdTable
 where key between 1 and 3;

select max(ymd) Keep(Dense_Rank Last order by ymd) as ymd
  from ymdTable
 where key between 3 and 5;


解説

count(*)とcount(ymd)を比較する方法は、
HAVING句の力の、「NULLを含まない集合を探す」を流用してます。

10-173 全称命題と存在命題で論理積(group化版)