我有一个获取上个月第一天的函数,但我想了解“ DATEDIFF(month,-1,getdate())-2”部分对获取上个月第一天的贡献月。完整的功能以代码形式给出。
我知道dateadd和datediff函数的作用,但是我不确定-1(在datediff函数中)和-2在dateadd函数中的作用。
SELECT @prev_month_first_date = DATEADD(month, DATEDIFF(month, -1, getdate()) - 2, 0)
答案 0 :(得分:5)
像这样重写它:
DATEADD(month, DATEDIFF(month, '20100101', getdate()) - 1, '20100101')
可能使其更清晰。
发生了一些模糊的事情。
此
DATEDIFF(month, -1, getdate())
计算两个日期之间的月份边界,第一个是
cast(-1 as datetime) --1899-12-31 00:00:00.000
然后从中减去2,然后将多个月加到
cast(0 as datetime) --1900-01-01 00:00:00.000
答案 1 :(得分:2)
-1代表从“零日期”(1900-01-01)开始的天数:
SELECT CONVERT(datetime, -1);
-- 1899-12-31 0:00
这是一种隐秘的方式,它只是获取开始日期以对之执行datediff,例如:
SELECT DATEDIFF(month, -1, getdate());
-- or
SELECT DATEDIFF(month, '18991231', getdate());
-- Both yield:
1431
因此表达式变为:
SELECT DATEADD(month, (1431 - 2), 0);
哪个是“将1429个月添加到零日期(1900-01-01)”:
SELECT DATEADD(month, (1431 - 2), '19000101');
哪种产量:
2019-02-01 0:00
再次0
和-1
只是神奇的数字,代表两个在秘密和“聪明”计算中使用的球门柱日期。
我个人觉得这样聪明的魔术令人困惑和无益。前一个月的开始也可以用以下表达式表示,实际上是更少的字符 用英语易于理解(从今天(两个月,即1月25日)减去两个月,移至该结尾月(1月31日),然后添加一天(2月1日)):
SELECT DATEADD(DAY,1,EOMONTH(DATEADD(MONTH,-2,GETDATE())));
只是证明有很多方法可以使这只猫皮肤化。戈登的DATEFROMPARTS
同样有效,我实际上不能忍受EOMONTH()
函数,但是这种形式只允许您指定一次GETDATE()
。
答案 2 :(得分:0)
我建议您使用这样的东西:
select dateadd(month, -1, datefromparts(year(getdate(), month(getdate(), 1))
这样做的意图要明确得多。