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

10-132 大小比較で場合分け

SQLパズル

料金テーブル
基本料金   開始日付  終了日付
--------  --------  --------
   7,300     01/06     07/01
   5,800     07/02     01/05

指定日を指定し、基本料金を求める。
日付は、mm/dd形式とする

出力結果
基本料金  指定日
--------  ------
   5,800   01/01
   5,800   01/01
   5,800   01/02
   5,800   01/03
   5,800   01/04
   5,800   01/05
   7,300   01/06
   7,300   01/07
   7,300   01/08
   7,300   01/09
   7,300   01/10

こちらを参考にさせていただきました


SQL

--■■■andとorを組み合わせる方法■■■
select b.基本料金,a.指定日
from (select to_char(trunc(sysdate,'yyyy')+rownum-1,'mm/dd') as 指定日
        from all_catalog where rownum <=366) a,
     (select '7,300' as 基本料金,'01/06' as 開始日付,'07/01' as 終了日付 from dual
union select '5,800','07/02','01/05' from dual) b
where b.開始日付 <= b.終了日付
  and a.指定日 between b.開始日付 and b.終了日付
   or b.開始日付 > b.終了日付
  and (a.指定日 between b.開始日付 and '12/31'
    or a.指定日 between '01/01'    and b.終了日付)
order by 指定日;

--■■■case式を使う方法■■■
select b.基本料金,a.指定日
from (select to_char(trunc(sysdate,'yyyy')+rownum-1,'mm/dd') as 指定日
        from all_catalog where rownum <=366) a,
     (select '7,300' as 基本料金,'01/06' as 開始日付,'07/01' as 終了日付 from dual
union select '5,800','07/02','01/05' from dual) b
where case when b.開始日付 <= b.終了日付
            and a.指定日 between b.開始日付 and b.終了日付 then 1
           when b.開始日付 > b.終了日付
            and (a.指定日 between b.開始日付 and '12/31'
              or a.指定日 between '01/01'    and b.終了日付) then 1 else 0 end = 1
order by 指定日;


解説

開始日付 <= 終了日付
の場合と、
開始日付  > 終了日付
の場合とで、
場合分けを行ってます

場合分けは、
数学の問題を解く時によく使う手法です

クエリでの分岐は、
条件に応じた、値の分岐なら、case式、
条件に応じた、条件の分岐なら、場合分け、
といった感じになります

case式を使う方法では、
andとorの組み合わせが複雑なクエリを、
検索case式で分かりやすくする方法を使ってます

場合分けの資料