来自DATEADD文档:
如果datepart是月份,而日期月份的天数多于返回日期 月份和日期日在返回月份中不存在,最后一个月 返回月份的日期。例如,九月有30 天;因此,以下两个陈述将于2006-09-30回归 00:00:00.000:
SELECT DATEADD(月,1,'2006-08-30');
SELECT DATEADD(month,1,'2006-08-31');
SQL Server
知道2016-03
的最后一天是31
而2016-04
的最后一天是30
:
SELECT DAY(EOMONTH('2016-03-01')) -- 31
SELECT DAY(EOMONTH('2016-04-01')) -- 30
然后为什么以下:
SELECT DATEADD(MONTH, -1, '2016-04-30')
返回2016-03-30 00:00:00.000
而不是2016-03-31 00:00:00.000
?
另外,如果我有以下内容:
SELECT DATEADD(MONTH, -1, '2016-03-31')
它正确返回2016-02-29 00:00:00.000
。
答案 0 :(得分:1)
正如其他评论所说,如果上个月的某一天存在,DATEADD将使用它,而不是假设您想要"该月的最后一天"。
如果你确实想要"那个月的最后一天",你将不得不扼杀更多的逻辑,例如:
DECLARE @date DATETIME = '30 April 2016'
SELECT CASE WHEN DATEDIFF(MONTH, @date, DATEADD(DAY, 1, @date)) = 1 THEN DATEADD(DAY, -1, DATEADD(MONTH, DATEDIFF(MONTH, 0, @date), 0))
ELSE DATEADD(MONTH, -1, @date)
END
这将假设如果它是该月的最后一天,则需要上个月的最后一天,而不是明确的28,29或30日。
答案 1 :(得分:0)
它不适用于从30开始的正数 - > 31,例如:
SELECT DATEADD(MONTH, 1, '2016-09-30')
产生2016-10-30 00:00:00.000
而不是2016-10-31 00:00:00.000
据推测,这是因为你不能在一个月内有30天的第31天,它会超过日期字段,但是你可以在一个月内有30个月,31天就可以了。
答案 2 :(得分:0)
日期添加功能的简单工作流程
即。 为日 - 即添加日(下一个有效日) 对于周 - 是添加周(接下来的7天) 月份 - 即添加月份(仅限下个月,如果日期无效,则填写) 年度 - 即年度
SELECT DATEADD(MONTH, -1, '2016-03-31')
output:
2016-02-29 00:00:00.000
:
2016-03-31 - 2016-02-31(减去1个月)但这不是一个有效的日期,所以函数尝试向后填充(在负面)\ fill forward date(正面)。 所以下一个有效的落后日期是2016-02-29。
总结: 功能用于向前填充和向后填充。