SQL Sever-奇怪的DateDiff行为

问题描述 投票:0回答:2

我有以下简单查询

select DATEADD(MONTH, DATEDIFF(MONTH, -32, '2020-02-29')-32, -1)
select DATEADD(MONTH, DATEDIFF(MONTH, -31, '2020-02-29')-31, -1)

我希望每行的输出会有所不同,因为-31和-32的月份数不同。

这两行都返回2017-07-31 00:00:00.000,我绝对不知道为什么!

有人可以向我解释吗?

sql sql-server datediff
2个回答
1
投票

documentationdateadd()中所述:

如果满足以下条件:

  • 日期部分是月份
  • 日期月份比返回月份的天数更多
  • 返回月份中不存在日期的日期

然后,DATEADD返回返回月份的最后一天。


1
投票

根据我的评论:

您为什么期望不同的值? DATEDIFF(MONTH, -32, '20200229')-32DATEDIFF(MONTH, -31, '20200229')-31都得到值1411。 “日期” -11899-12-31,并在其上加上1411个月(117年7个月)。

让我们分解一下:

2017-07-31

这将返回以下内容:

SELECT DATEDIFF(MONTH, -32, '20200229')-32 AS DD1, DATEDIFF(MONTH, -31, '20200229')-31 AS DD2;

我们也可以将以上内容分解为进一步的步骤。对于DD1 DD2 ----------- ----------- 1411 1411 ,日期datetime0,每个完整的整数表示该日期增加了很多天。因此,1900-01-01作为日期是-32,而1899-11-30-31。这给了我们下面的2个表达式:

1899-12-01

这将返回以下内容:

SELECT DATEDIFF(MONTH, '18991130', '20200229') AS M1, DATEDIFF(MONTH, '18991201', '20200229') AS M2;

这很有意义,因为M1 M2 ----------- ----------- 1443 1442 计算2个日期之间的“滴答声”数量。因此,对于表达式DATEDIFF,即使仅经过了1毫秒,也会返回值DATEDIFF(YEAR, '2019-12-31T23:59:59.9999999','2020-01-01T00:00:00.000000'),因为年份的值已更改(乘以1)。

该表达式的下一部分分别是11443 - 32。两者(基础数学)均为1442 - 31

然后便有了“日期” 1411。然后,将-1个月(117年零7个月)添加到日期1411,该日期(毫不奇怪)返回相同的值:1899-12-312017-07-311899 + 117 = 2016因为我们要在几个月内工作,所以将12 + 7 = 7携带到年份:1

© www.soinside.com 2019 - 2024. All rights reserved.