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

How to write a variable within SQL using Dateadd and DateDiff for finding the last TWO days of the previous month

我正在尝试使用显示上个月最后两天的 dateadd 和 datediff 编写一个变量。一个变量将是上个月的倒数第二天,我遇到了麻烦。另一个将是上个月的最后一天,我能够得到的那一天。我正在使用 SQL 服务器。

我试过在 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。相反,我想要 2/27/2019

我也得到了 2/28/2019 的 lastdayprevmonth,这正是我想要的。

我正在编写变量,因为当前月份每个月都会发生变化,而不必更新我在查询中需要的其他日期,我想使用变量,所以我只更新当前月份,其他一切都是流过。

以及关于为什么我的 dateadd/datediff 错误的解释以及为什么正确的 dateadd/datediff 是这样的解释,将非常有帮助

为什么计算倒数第二天不参考最后一天?另外,您对 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 来计算上个月的最后一天,这 returns 给定月份的最后一天。那么倒数第二天只是从中减去一天。

产量:

SecLastDayPrevMonth LastDayPrevMonth
------------------- ----------------
2019-02-27          2019-02-28

至于"why",DATEDIFF()需要3个参数:datepart(特定日期部分的字符串表示),startdateenddate(两者都是其中必须可转换为日期对象)。

0 本质上是 SQL 的纪元,在本例中是 1/1/1900。所以 0 和 3/1/2019 之间的月份差是 (119*12)+2(+2 因为我们不包括三月,因为我们没有计算完整的月份)= 1430 个月的差异。

然后,我们正在努力为我们的价值增加 2 个月。 DATEADD() 接受 3 个参数:datepartnumberdate。但是,在示例中,您要将 1430 个月添加到转换为 -2 的任何日期(在这种情况下,我相信它将是 12/30/1899,或纪元前 2 天)。因此,12/30/1899 之后的 1430 个月将是 2/30/2019,但 2 月在 2019 年只有 28 天,因此 returns 2/28/2019。在闰年,它可能会 return 2/29/2019。

要仅使用 DATEDIFF()DATEADD() 得到 @LastDayPrevMonth@SecLastDayPrevMonth,您只需稍微更改一下计算即可。

您要做的第一件事是找到给定月份的第一天。这可以用 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() 函数可以更轻松地完成这一切,以到达一个月的最后一天。但是,如果您只能使用原始问题中的两个原始函数,这将是获得所需值的一种方法。