SQL:从上个月的第二个工作日获取值

时间:2016-05-19 10:23:04

标签: sql-server

我有一张表,其中包含每个日期,货币和国家/地区的历史cash_balances。

我需要填写一个名为“cash_balance_last_month”的列,其中包含上个月第二个工作日的“cash_balance”列中的值 - 这个值被定义为上个月中有数据的第二个最后一个日期在表中。

所以表格如下:

report_date / currency / country / cash_balance / cash_balance_last_month
2016-03-05  /   USD    /   US    /      110     /        NULL
2016-03-05  /   EUR    /   DE    /      130     /        NULL
2016-03-05  /   EUR    /   FR    /      240     /        NULL
2016-02-05  /   USD    /   US    /      105     /        NULL
2016-02-05  /   EUR    /   DE    /      125     /        NULL
2016-02-05  /   EUR    /   FR    /      245     /        NULL
2016-29-04  /   USD    /   US    /      100     /        NULL
2016-29-04  /   EUR    /   DE    /      120     /        NULL
2016-29-04  /   EUR    /   FR    /      250     /        NULL
2016-28-04  /   USD    /   US    /       95     /        NULL
2016-28-04  /   EUR    /   DE    /      115     /        NULL
2016-28-04  /   EUR    /   FR    /      255     /        NULL
...
2016-30-03  /   USD    /   US    /       90     /        NULL
2016-30-03  /   EUR    /   DE    /      117     /        NULL
2016-30-03  /   EUR    /   FR    /      257     /        NULL

请注意,2016-30-03是3月的第二个工作日。

表格应如下所示:

report_date / currency / country / cash_balance / cash_balance_last_month
2016-03-05  /   USD    /   US    /      110     /        95
2016-03-05  /   EUR    /   DE    /      130     /        115
2016-03-05  /   EUR    /   FR    /      240     /        255
2016-02-05  /   USD    /   US    /      105     /        95
2016-02-05  /   EUR    /   DE    /      125     /        115
2016-02-05  /   EUR    /   FR    /      245     /        255
2016-29-04  /   USD    /   US    /      100     /        90
2016-29-04  /   EUR    /   DE    /      120     /        117
2016-29-04  /   EUR    /   FR    /      250     /        257
2016-28-04  /   USD    /   US    /       95     /        90
2016-28-04  /   EUR    /   DE    /      115     /        117
2016-28-04  /   EUR    /   FR    /      255     /        257
...
2016-30-03  /   USD    /   US    /       90     /        NULL
2016-30-03  /   EUR    /   DE    /      117     /        NULL
2016-30-03  /   EUR    /   FR    /      257     /        NULL

第一个条目,在本例中为2016-30-03,显然没有上个月可以引用。

如何计算此栏目“cash_balance_last_month”?我无法自己弄明白或找到任何可以帮助我找到解决方案的相关问题。

非常感谢帮助。谢谢!

1 个答案:

答案 0 :(得分:1)

declare @table table
(report_date datetime , currency varchar(3),  country varchar(2), cash_balance int, cash_balance_last_month int)
insert into @table
values
(cast('2016-05-03'  as datetime),   'USD'    ,   'US'    ,      110     ,        NULL),
(cast('2016-05-03'  as datetime),   'EUR'    ,   'DE'    ,      130     ,        NULL),
(cast('2016-05-03'  as datetime),   'EUR'    ,   'FR'    ,      240     ,        NULL),
(cast('2016-05-02'  as datetime),   'USD'    ,   'US'    ,      105     ,        NULL),
(cast('2016-05-02'  as datetime),   'EUR'    ,   'DE'    ,      125     ,        NULL),
(cast('2016-05-02'  as datetime),   'EUR'    ,   'FR'    ,      245     ,        NULL),
(cast('2016-04-29'  as datetime),   'USD'    ,   'US'    ,      100     ,        NULL),
(cast('2016-04-29'  as datetime),   'EUR'    ,   'DE'    ,      120     ,        NULL),
(cast('2016-04-29'  as datetime),   'EUR'    ,   'FR'    ,      250     ,        NULL),
(cast('2016-04-28'  as datetime),   'USD'    ,   'US'    ,       95     ,        NULL),
(cast('2016-04-28'  as datetime),   'EUR'    ,   'DE'    ,      115     ,        NULL),
(cast('2016-04-28'  as datetime),   'EUR'    ,   'FR'    ,      255     ,        NULL),
(cast('2016-03-31'  as datetime),   'USD'    ,   'US'    ,       10     ,        NULL),
(cast('2016-03-31'  as datetime),   'EUR'    ,   'DE'    ,       10     ,        NULL),
(cast('2016-03-31'  as datetime),   'EUR'    ,   'FR'    ,       10     ,        NULL),
(cast('2016-03-30'  as datetime),   'USD'    ,   'US'    ,       90     ,        NULL),
(cast('2016-03-30'  as datetime),   'EUR'    ,   'DE'    ,      117     ,        NULL),
(cast('2016-03-30'  as datetime),   'EUR'    ,   'FR'    ,      257     ,        NULL)

select  t1.report_date,t1.currency,t1.country,t1.cash_balance, s.cash_balance as cash_balance_last_month
from    @table t1
left join
(
select  t1.*,
        year(t1.report_date) * 12 +  month(t1.report_date) monthnum,
        row_number() over(partition by  year(t1.report_date) * 100 + month(t1.report_date), t1.country order by t1.report_date desc) rn
from    @table t1
) s
on  s.monthnum = (year(t1.report_date) * 12 +  month(t1.report_date))  - 1
    and t1.country = s.country and t1.currency = s.currency 
    and s.rn = 2