我正在尝试使用dateadd和datediff编写一个变量,该变量显示上个月的最后两天。一个变量将是上个月的第二天到最后一天,这是我遇到的麻烦。另一个将是上个月的最后一天,即我能够获得的那一天。我正在使用SQL Server。
我尝试在Stack上查找它,但只看到了上个月的最后一天,而不是倒数第二天。我尝试学习dateadd和datediff(我仍然想做)。
这是我到目前为止尝试过的:
Declare @CurrentMonth as date = '3/1/2019'
Declare @SecLastDayPrevMonth as date = DATEADD(MONTH, DATEDIFF(MONTH, 0, @currentmonth), -2)
Declare @LastDayPrevMonth as date = DATEADD(MONTH, DATEDIFF(MONTH, 0, @currentmonth), -1)
我在seclastdayPrevMonth获得的结果是2/28/2019。相反,我想要2019/2/27
我也想要在lastdayprevmonth获得2019/2/28的信息。
我写变量是因为当前月份每个月都会变化,而不是必须更新查询中需要的其他日期,我想使用变量,所以我只更新当前月份,其他所有内容。
解释为什么我的dateadd / datediff是错误的,并解释为什么正确的dateadd / datediff就是这样,
答案 0 :(得分:3)
为什么在计算倒数第二天时不参考最后一天?另外,您对DATEADD
的使用也很奇怪。语法为DATEADD(interval, increment, datetime)
Declare @recmonth as date = '3/1/2019'
Declare @LastDayPrevMonth as date = EOMONTH(DATEADD(MONTH, -1, @RecMonth))
Declare @SecLastDayPrevMonth as date = DATEADD(DAY, -1, @LastDayPrevMonth)
SELECT @SecLastDayPrevMonth, @LastDayPrevMonth
因此,我们可以通过从日期中减去一个月然后调用EOMONTH
来计算上个月的最后一天,该操作将返回给定月份的最后一天。然后倒数第二天就是从中减去一天。
收益:
SecLastDayPrevMonth LastDayPrevMonth
------------------- ----------------
2019-02-27 2019-02-28
答案 1 :(得分:0)
关于“为什么”,DATEDIFF()
接受3个参数:datepart
(特定日期部分的字符串表示形式),startdate
,enddate
(两者都必须是可转换为类似日期的对象。
0
本质上是SQL的纪元,在这种情况下为1/1/1900
。因此,0和3/1/2019
之间的月份差异为(119 * 12)+2(+2,因为我们排除了3月,因为我们没有计算一个完整的月份),因此得出1430个月差异。
然后,我们尝试将价值增加2个月。 DATEADD()
接受3个参数:datepart
,number
,date
。但是,在此示例中,您将-2转换为的任何日期都添加了1430个月(在这种情况下,我相信它将是12/30/1899,即纪元前2天)。因此,在12/30/1899之后的1430个月将是2/30/2019,但是2月在2019年只有28天,因此它将返回2/28/2019。在a年,它可能会返回2/29/2019。
要只用@LastDayPrevMonth
和@SecLastDayPrevMonth
来获得DATEDIFF()
和DATEADD()
,您只需要稍微改变一下计算即可。
您要做的第一件事是找到给定月份的第一天。可以使用DATEADD(month,DATEDIFF(month,0,@CurrentDate),0)
完成。本质上,我们使用的是与上述相同的东西,用于计算自纪元以来的月数,但随后我们将这些月加回到纪元。
现在我们知道了给定月份的第一天,我们要做的就是减去上个月的天数。
所以
DECLARE @CurrentDate date = '2019-03-15' ; -- Changed it to something in the middle of the month.
DECLARE @FirstDayOfGivenMonth = DATEADD(month,DATEDIFF(month,0,@CurrentDate),0) ; -- 3/1/2019
DECLARE @LastDayOfPrevMonth date = DATEADD(day,-1,@FirstDayOfThisMonth) ; -- 2/28/2019
DECLARE @SecLastDayOfPrevMonth date = DATEADD(day, -2, @FirstDayOfThisMonth) ; -- 2/27/2019
SELECT @LastDayOfPrevMonth AS LDPM, @SecLastDayOfPrevMonth AS SLDPM ;
DECLARE @FourDaysLeftInPrevMonth date = DATEADD(day, -4, @FirstDayOfThisMonth) ; -- 2/25/2019
SELECT @FourDaysLeftInPrevMonth AS FourDaysLeftPrev ;
自从SQL 2012开始,使用EOM()
函数可以轻松完成所有工作,直到一个月的最后一天。但是,如果您只能使用原始问题中的两个原始函数,那将是获得所需值的一种方法。