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

5-64 not existsで存在否定命題の論理和

SQLパズル

empTable1             empTable2
      Day1  Stat            Day1  Stat
----------  ----      ----------  ----
2008-05-01     1      2008-05-02     1
2008-05-03     1      2008-05-04     0
2008-05-04     0      2008-05-06     0
2008-05-05     1      2008-05-08     1
2008-05-06     1

Statの0が休日、1が出勤日として、
2008/05/03以降で、少なくとも片方のテーブルが出勤になっている5日分のリストを出力する。
なお、未入力の日も、出勤扱いとする。

出力結果
      Day1
----------
2008-05-03
2008-05-05
2008-05-06
2008-05-07
2008-05-08


データ作成スクリプト

create table empTable1(Day1,Stat) as
select date '2008-05-01',1 from dual union
select date '2008-05-03',1 from dual union
select date '2008-05-04',0 from dual union
select date '2008-05-05',1 from dual union
select date '2008-05-06',1 from dual;

create table empTable2(Day1,Stat) as
select date '2008-05-02',1 from dual union
select date '2008-05-04',0 from dual union
select date '2008-05-06',0 from dual union
select date '2008-05-08',1 from dual;

alter table empTable1 add check(Stat in('0','1'));
alter table empTable2 add check(Stat in('0','1'));


SQL

select Day1
from (select Day1
      from (select date '2008-05-03' + RowNum -1 as Day1
              from all_objects
             where RowNum <= 5000) a
       where not exists(select 1 from empTable1 b
                         where b.Stat = 0
                           and b.Day1 = a.Day1)
          or not exists(select 1 from empTable2 b
                         where b.Stat = 0
                           and b.Day1 = a.Day1)
      order by Day1)
 where RowNum <= 5;


解説

未入力の日も、出勤扱いとなるので、
not existsでstatが0のレコードの存在を調べると
シンプルになると考えました。

結果として、存在否定命題の論理和を見ています。