2016-04-26 2 views
2

SQLサーバーに複数の有価証券の累積リターンを含むテーブルがあります。テーブル内で更新されなくなったアイテムの最終価値を引き継ぐ

表は次のようになります。

report_date/security_id/return_usd 
--------------------------------------- 
2016-02-21/security_a /2.0 
2016-02-22/security_a /-1.2 
2016-02-23/security_a /-2.7 
2016-02-21/security_b /5.2 

問題は累積リターンは、(上記の例のように、セキュリティB)を販売されているか、成熟している有価証券のために消えるということです。

私は以下の例のように、これらの証券の前方最後の値(return_usd)を運ぶために継続する必要がある

report_date/security_id/return_usd 
--------------------------------------- 
2016-02-21/security_a /2.0 
2016-02-22/security_a /-1.2 
2016-02-23/security_a /-2.7 
2016-02-21/security_b /5.2 
2016-02-22/security_b /5.2 
2016-02-23/security_b /5.2 

それははるかになるので、残念ながら、私は自分自身をそれを把握することができていません誰かが私を助けることができれば幸いです

答えて

1

すべての証券と日付の行が必要な場合は、その合計を引き継ぐように見えます。 CROSS JOINを使用して行を生成できます。その後、SQL Serverの2012+に、あなたはLAG()を使用することができます。

select d.report_date, s.security_id, 
     coalesce(t.return_usd, 
       lag(t.return_usd) over (partition by s.security_id 
             order by (case when t.return_usd is not null then 1 else 2 end), d.report_date 
             ) 
       ) as return_usd 
from (select distinct report_date from t) d cross join 
    (select distinct security_id from t) s left join 
    t 
    on t.report_date = d.report_date and t.security_id = s.security_id; 

注:これは、以前の非NULL値と任意のNULL値で埋めます。あなたが最後の前にギャップがなければ、これはあなたが望むものでなければなりません。

EDIT:

これもouter applyや相関サブクエリを使用して書くことができます。

select d.report_date, s.security_id, 
     (select top 1 t.return_usd 
     from t 
     where t.report_date <= d.report_date and t.security_id = d.security_id and 
       t.return_usd is not null 
     order by t.report_date desc 
     ) as return_usd 
from (select distinct report_date from t) d cross join 
    (select distinct security_id from t) s left join 
    t 
    on t.report_date = d.report_date and t.security_id = s.security_id; 

これは、SQL Serverの以前の(サポート)のバージョンで動作します。

+0

ありがとうございます。出来た。しかし、私はそれがs.security_idでなければならないと思うし、d.security_idではなく、2番目のソリューションではないでしょうか? – SSA

+0

@SSA。 。 。ありがとうございました。 –

関連する問題