如何从日期列中减去一个月

How to subtract one month from a Date Column

我知道 Dateadd 和 datediff,但我找不到任何信息如何在实际日期列上使用这些函数,而不是在 SQL 服务器上使用今天的日期。

假设我有以下专栏

Dated
06/30/2015
07/31/2015

现在我想添加以下派生列,从日期列中的每一行减去一个月。

Dated             Subtracted
06/30/2015        05/31/2015
07/31/2015        06/30/2015

谢谢

简短的回答:我怀疑这就是你想要的:

dateadd(day, -datepart(day, Dated), Dated)

但是,如果您希望 "regular" 在坚持到月末的同时减去一个月的行为,将 6 月 30 日回落到 5 月 31 日会稍微有点棘手。标题或您的问题与您希望固定月份的最后一天的示例之间存在差异。澄清这一点对您很有帮助。

dateadd(month, -1, ...) 不会处理上个月的天数比开始月份多的情况,尽管它是相反的。如果那确实是您所需要的,我认为这应该可以解决:

case
    when datediff(month, Dated, dateadd(day, 1, Dated)) = 1
    then dateadd(day, -datepart(day, Dated), Dated)
    else dateadd(month, -1, Dated)
end

该表达式中还有几个日期函数的风格,以及这种日期内容如何变得复杂的感觉。 when 中的条件通过检查下一天是否在不同的日历月中来查看 Dated 是否是该月的最后一天。如果是这样,我们提取月份中的第几天并减去那么多天以跳回到上个月的最后一天。 (月份从一开始,而不是零。因此,例如,从前一个月的第 17 块土地向后计算 17 天。)否则它会使用常规 dateadd(month, -1, ...) 计算向后跳到该月的同一天。

当然,如果所有你的约会都在月底,那么这个简单的版本本身就足够了,因为它总是returns最后一天上个月(无论它落在起始月份的哪个位置):

dateadd(day, -datepart(day, Dated), Dated) /* refer back to the top */
dateadd(day, -day(Dated), Dated) /* same thing */

为了好玩和练习日期表达式,另一种方法是您可以从一个已知的有 31 天的月份开始,并相对于该月份进行计算:

dateadd(month, datediff(month, '20151231', Dated) - 1, '20151231')

这会找到您的日期和参考日期之间的月数。它适用于所有日期,因为差异是正数还是负数都没有关系。因此,然后从该差异中减去一个并在参考点上添加那么多个月就是您想要的结果。

人们会想出一些非常疯狂的东西,而我经常对我看到的一些变化感到惊讶(出于不同的原因)。 chancrovsky 的回答是仔细检查的一个很好的例子:

dateadd(month, datediff(month, -1, Dated) - 1, -1)

它依赖于日期 -1,当被视为隐式转换为 datetime 时,是 1900 年 1 月 1 日之前的一天,恰好是 31 天的月份必需的。 (请注意,中间的 - 1 是常规算术而不是日期值。)我想大多数人会建议您小心使用那个,因为我不确定它是否保证在 Microsoft 时是可移植的将来会弃用功能。

为什么不只获取上个月的最后一天?如果这解决了您的问题,这里是 sql 服务器语法,只需将变量 @yourDate 替换为您的列名即可。

DECLARE @yourDate DATE = '20160229'
select DATEADD(MONTH, DATEDIFF(MONTH, -1, @yourDate)-1, -1)

如果您要查找正好晚 6 个月的日期,这也适用。

示例:

DATEADD(DAY, DATEDIFF(DAY, -1, dates)-184, -31)