トップページに戻る
次のSQLパズルへ
前のSQLパズルへ
9-55 ランを求める
SQLパズル
株価推移テーブル
年月 株価
---------- ----
2007/01/06 1000
2007/01/08 1050
2007/01/09 1100
2007/01/12 900
2007/01/13 880
2007/01/14 870
2007/01/16 920
2007/01/17 1000
株価が、右肩上がりな期間を
以下の形式で出力する。
出力結果
開始年月 終了年月
---------- ----------
2007/01/06 2007/01/09
2007/01/13 2007/01/17
プログラマのためのSQL第2版の24章[リージョン、ラン、シーケンス]を参考にさせていただきました。
データ作成スクリプト
create table 株価推移 as
select to_date('2007/01/06','yyyy/mm/dd') as 年月,1000 as 株価 from dual
union select to_date('2007/01/08','yyyy/mm/dd'),1050 from dual
union select to_date('2007/01/09','yyyy/mm/dd'),1100 from dual
union select to_date('2007/01/12','yyyy/mm/dd'), 900 from dual
union select to_date('2007/01/13','yyyy/mm/dd'), 880 from dual
union select to_date('2007/01/14','yyyy/mm/dd'), 870 from dual
union select to_date('2007/01/16','yyyy/mm/dd'), 920 from dual
union select to_date('2007/01/17','yyyy/mm/dd'),1000 from dual;
SQL
select min(年月) as 開始年月,max(年月) as 終了年月
from (select 年月,株価,sum(WillSum) over(order by 年月) as makeGroup
from (select 年月,株価,
case when lnnvl(株価 > Lag(株価) over(order by 年月))
then 1 else 0 end as WillSum
from 株価推移))
group by makeGroup
having count(*) > 1
order by min(年月);
解説
case式とLag関数とSum関数を組み合わせてます。
Lag関数を使った行間比較がありますので、
旅人算の感覚を使わないほうがシンプルでしょう。
CodeZine:SQLで数列を扱う