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

8-6 サイコロジカルを求める

SQLパズル

サイコロジカルテーブル
日付        終値
----------  ----
2006/03/01  1462
2006/03/02  1458
2006/03/03  1464
2006/03/04  1460
2006/03/07  1469
2006/03/08  1473
2006/03/09  1483
2006/03/10  1482
2006/03/11  1482
2006/03/14  1494
2006/03/15  1489
2006/03/16  1481
2006/03/17  1491
2006/03/18  1483
2006/03/22  1456
2006/03/23  1451
2006/03/24  1458

12日サイコロジカルを求める(小数第3位を切り捨てる)

出力結果
日付        終値  前日比  サイコロジカル
----------  ----  ------  --------------
2006/03/01  1462    null            null
2006/03/02  1458    null            null
2006/03/03  1464       +            null
2006/03/04  1460    null            null
2006/03/07  1469       +            null
2006/03/08  1473       +            null
2006/03/09  1483       +            null
2006/03/10  1482    null            null
2006/03/11  1482    null            null
2006/03/14  1494       +            null
2006/03/15  1489    null            null
2006/03/16  1481    null           41.66    (3/1から3/16の上昇日数)/12×100
2006/03/17  1491       +           50.00    (3/2から3/17の上昇日数)/12×100
2006/03/18  1483    null           50.00    (3/3から3/18の上昇日数)/12×100
2006/03/22  1456    null           41.66    (3/4から3/22の上昇日数)/12×100
2006/03/23  1451    null           41.66    (3/7から3/23の上昇日数)/12×100
2006/03/24  1458       +           41.66    (3/8から3/24の上昇日数)/12×100


データ作成スクリプト

create table サイコロジカル as
select to_date('2006/03/01','YYYY/MM/DD') as 日付,1462 as 終値 from dual
union select to_date('2006/03/02','YYYY/MM/DD'),1458 from dual
union select to_date('2006/03/03','YYYY/MM/DD'),1464 from dual
union select to_date('2006/03/04','YYYY/MM/DD'),1460 from dual
union select to_date('2006/03/07','YYYY/MM/DD'),1469 from dual
union select to_date('2006/03/08','YYYY/MM/DD'),1473 from dual
union select to_date('2006/03/09','YYYY/MM/DD'),1483 from dual
union select to_date('2006/03/10','YYYY/MM/DD'),1482 from dual
union select to_date('2006/03/11','YYYY/MM/DD'),1482 from dual
union select to_date('2006/03/14','YYYY/MM/DD'),1494 from dual
union select to_date('2006/03/15','YYYY/MM/DD'),1489 from dual
union select to_date('2006/03/16','YYYY/MM/DD'),1481 from dual
union select to_date('2006/03/17','YYYY/MM/DD'),1491 from dual
union select to_date('2006/03/18','YYYY/MM/DD'),1483 from dual
union select to_date('2006/03/22','YYYY/MM/DD'),1456 from dual
union select to_date('2006/03/23','YYYY/MM/DD'),1451 from dual
union select to_date('2006/03/24','YYYY/MM/DD'),1458 from dual;


SQL

--■■■分析関数を使う方法■■■
select to_char(日付,'yyyy/mm/dd') as 日付,終値,
case when 終値 > Lag終値 then '+' end as 前日比,
case when count(*) over(order by 日付) >= 12
then to_char(trunc(sum(case when 終値 > Lag終値 then 1 else 0 end)
     over(order by 日付 Rows (12-1) Preceding)/12*100,2),'999.99') end as サイコロジカル
from (select 日付,終値,Lag(終値) over(order by 日付) as Lag終値
        from サイコロジカル);


解説

case式と分析関数を組み合わせてます。

分析関数を使わずに相関サブクエリでやる場合は、
ビューを作らないと複雑なクエリになるでしょう。