如何在SQL中使用Dateadd和DateDiff编写变量以查找上个月的最后两天

时间:2019-04-04 16:03:03

标签: sql sql-server datediff dateadd

我正在尝试使用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就是这样,

2 个答案:

答案 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(特定日期部分的字符串表示形式),startdateenddate(两者都必须是可转换为类似日期的对象。

0本质上是SQL的纪元,在这种情况下为1/1/1900。因此,0和3/1/2019之间的月份差异为(119 * 12)+2(+2,因为我们排除了3月,因为我们没有计算一个完整的月份),因此得出1430个月差异。

然后,我们尝试将价值增加2个月。 DATEADD()接受3个参数:datepartnumberdate。但是,在此示例中,您将-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()函数可以轻松完成所有工作,直到一个月的最后一天。但是,如果您只能使用原始问题中的两个原始函数,那将是获得所需值的一种方法。