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

3-30 初旬、中旬、下旬で集計

SQLパズル

ValTable
   sellDay  Val
----------  ---
2007/01/01  150
2007/01/04  200
2007/01/09  250
2007/01/10  300
2007/01/11  350
2007/01/15  400
2007/01/19  450
2007/01/20  500
2007/01/21  550
2007/01/30  600
2007/01/31  650
2007/02/09  700
2007/02/10  750
2007/02/11  800
2007/02/19  850
2007/02/20  900
2007/02/21  950
2007/02/27  960
2007/02/28  970

各年月の、
初旬( 1日から10日まで)
中旬(11日から20日まで)
下旬(21日から末日まで)
で集計する

出力結果
      sellDay   Val
-------------  ----
2007年1月初旬   900  ← 150+200+250+300
2007年1月中旬  1700  ← 350+400+450+500
2007年1月下旬  1800  ← 550+600+650
2007年2月初旬  1450  ← 700+750
2007年2月中旬  2550  ← 800+850+900
2007年2月下旬  2880  ← 950+960+970


データ作成スクリプト

create table ValTable as
select to_date('2007/01/01','YYYY/MM/DD') as sellDay,150 as Val from dual
union select to_date('2007/01/04','YYYY/MM/DD'),200 from dual
union select to_date('2007/01/09','YYYY/MM/DD'),250 from dual
union select to_date('2007/01/10','YYYY/MM/DD'),300 from dual
union select to_date('2007/01/11','YYYY/MM/DD'),350 from dual
union select to_date('2007/01/15','YYYY/MM/DD'),400 from dual
union select to_date('2007/01/19','YYYY/MM/DD'),450 from dual
union select to_date('2007/01/20','YYYY/MM/DD'),500 from dual
union select to_date('2007/01/21','YYYY/MM/DD'),550 from dual
union select to_date('2007/01/30','YYYY/MM/DD'),600 from dual
union select to_date('2007/01/31','YYYY/MM/DD'),650 from dual
union select to_date('2007/02/09','YYYY/MM/DD'),700 from dual
union select to_date('2007/02/10','YYYY/MM/DD'),750 from dual
union select to_date('2007/02/11','YYYY/MM/DD'),800 from dual
union select to_date('2007/02/19','YYYY/MM/DD'),850 from dual
union select to_date('2007/02/20','YYYY/MM/DD'),900 from dual
union select to_date('2007/02/21','YYYY/MM/DD'),950 from dual
union select to_date('2007/02/27','YYYY/MM/DD'),960 from dual
union select to_date('2007/02/28','YYYY/MM/DD'),970 from dual;


SQL

select sellDay,sum(Val) as Val
from (select
      to_char(sellDay,'yyyy"年"fmmm"月"') ||
      case when extract(day from sellDay) <= 10 then '初旬'
           when extract(day from sellDay) <= 20 then '中旬'
           else '下旬' end as sellDay,
      Val
      from ValTable)
group by sellDay
order by substr(sellDay,1,instr(sellDay,'月')),
decode(substr(sellDay,-2),'初旬',1,'中旬',2,'下旬',3);


解説

date型から、日を
文字型で取り出したい場合は、to_char関数
数値型で取り出したい場合は、extract関数
といった感じで使い分けるといいでしょう