2016-04-26 48 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值。如果你在結束之前沒有空白,那麼這應該是你想要的。

編輯:

這也可以使用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在第二個解決方案中,對嗎? – SSA

+0

@SSA。 。 。謝謝。 –

相關問題