首页 > 解决方案 > 获取月份第一个日期的值

问题描述

我有每个产品库存的每周数据。我想按年分组并获得每个月的第一个值。换句话说,我想获得每个月的期初股票,而不是当月的哪一天。

+------------+---------+
|   MyDate   | MyValue |
+------------+---------+
| 2018-01-06 |       2 |*
| 2018-01-13 |       7 |
| 2018-01-20 |       5 |
| 2018-01-27 |       2 |
| 2018-02-03 |       3 |*
| 2018-02-10 |      10 |
| 2018-02-17 |       6 |
| 2018-02-24 |       4 |
| 2018-03-03 |       7 |*
| 2018-03-10 |       5 |
| 2018-03-17 |       3 |
| 2018-03-24 |       4 |
| 2018-03-31 |       6 |
+------------+---------+

期望的结果:

+----------------+---------+
| FirstDayOfMonth| MyValue |
+----------------+---------+
| 2018-01-01     |       2 |
| 2018-02-01     |       3 |
| 2018-03-01     |       7 |
+----------------+---------+

我认为这可能有效,但事实并非如此。

select 
    [product],
    datefromparts(year([MyDate]), month([MyDate]), 1),
    FIRST_VALUE(MyValue) OVER (PARTITION BY [Product], YEAR([MyDate]), MONTH([MyDate]) ORDER BY [MyDate] ASC) AS MyValue
from 
    MyTable 
group by 
    [Product],
    YEAR([MyDate]), MONTH([MyDate])

编辑. 谢谢你。我问题的重点不是如何获得本月的第一天。我知道有不同的技术。

重点是如何获得月份中的第一个值(期初股票)。如果有机会一口气获得收盘价——那就太好了。基于ROW_NUMBER不允许一次性获得收盘股票的答案,需要两个连接。

接受答案后编辑
请考虑 John Cappelletti 的答案作为已接受答案的替代方案:https ://stackoverflow.com/a/53559750/1903793

标签: sqlsql-servertsqldategreatest-n-per-group

解决方案


您可以使用apply&eomonth查找一个月的最后一天并添加一天:

select distinct dateadd(day, 1, eomonth(t1.mydate, -1)) as FistDayOfMonth, t1.myvalue
from table t cross apply
     ( select top (1) t1.mydate, t1.myvalue
       from table t1
       where t1.product = t.product and
             year(t1.MyDate) = year(t.MyDate) and month(t1.MyDate) = month(t.MyDate)
       order by t1.mydate
     ) t1;

推荐阅读