这个SQL函数如何获得上个月的第一天?

时间:2019-03-25 14:24:43

标签: sql sql-server

我有一个获取上个月第一天的函数,但我想了解“ DATEDIFF(month,-1,getdate())-2”部分对获取上个月第一天的贡献月。完整的功能以代码形式给出。

我知道dateadd和datediff函数的作用,但是我不确定-1(在datediff函数中)和-2在dateadd函数中的作用。

SELECT @prev_month_first_date = DATEADD(month, DATEDIFF(month, -1, getdate()) - 2, 0)

3 个答案:

答案 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))

这样做的意图要明确得多。