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

7-71 指定日より過去の平日を取得

SQLパズル

休日表テーブル
      休日
----------
2006/11/03
2006/11/04
2006/11/05
2006/11/11
2006/11/12
2006/11/18
2006/11/19
2006/11/23
2006/11/25
2006/11/26

指定日より過去の休日でない日を出力する。
指定日が2006/11/13なら、2006/11/10を出力
指定日が2006/11/12なら、2006/11/10を出力
指定日が2006/11/11なら、2006/11/10を出力
指定日が2006/11/10なら、2006/11/09を出力
指定日が2006/11/09なら、2006/11/08を出力
指定日が2006/11/06なら、2006/11/02を出力


SQL

def 指定日 = to_date('2006/11/13','yyyy/mm/dd')

with 休日表 as(
select to_date('2006/11/03','yyyy/mm/dd') as 休日 from dual
union select to_date('20061104','yyyy/mm/dd') from dual
union select to_date('20061105','yyyy/mm/dd') from dual
union select to_date('20061111','yyyy/mm/dd') from dual
union select to_date('20061112','yyyy/mm/dd') from dual
union select to_date('20061118','yyyy/mm/dd') from dual
union select to_date('20061119','yyyy/mm/dd') from dual
union select to_date('20061123','yyyy/mm/dd') from dual
union select to_date('20061125','yyyy/mm/dd') from dual
union select to_date('20061126','yyyy/mm/dd') from dual)
select
  case when exists(select 1 from 休日表
                    where 休日 = &指定日-1)
       then (select max(休日)-1
               from 休日表 a
              where 休日 <= &指定日-1
                and not exists(select 1 from 休日表 b
                                where b.休日 = a.休日-1))
       else &指定日-1 end as 稼働日
from dual;

def 指定日 = to_date('2006/11/12','yyyy/mm/dd')
/
def 指定日 = to_date('2006/11/11','yyyy/mm/dd')
/
def 指定日 = to_date('2006/11/10','yyyy/mm/dd')
/
def 指定日 = to_date('2006/11/09','yyyy/mm/dd')
/
def 指定日 = to_date('2006/11/06','yyyy/mm/dd')
/


解説

case式で、
第一候補が休日の場合と、休日でない場合を
場合分けしてます。