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

时间:2016-01-04 18:46:47

标签: sql sql-server dateadd

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

说我有以下列

Dated
06/30/2015
07/31/2015

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

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

谢谢

3 个答案:

答案 0 :(得分:4)

为什么不在上个月的最后一天?如果这解决了你的问题,这里是sql server语法,只需用你的列名替换变量@yourDate。

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

答案 1 :(得分:3)

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

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

然而,如果你想要“常规”减少一个月的行为并坚持到月底,那么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是否是该月的最后一天。如果是这样,我们提取月中的日期并减去那么多天以跳回到上个月的最后一天。 (月份从1开始而不是零。例如,从前一个月的第17个土地开始向后计算17天。)否则,它会使用常规dateadd(month, -1, ...)计算向后跳到月份的同一天。

当然如果所有你的日期落在月末,那么这个简单的版本本身就足够了,因为它总是返回上个月的最后一天(无论它在哪里落入)起始月份:

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中可移植将来弃用功能。

答案 2 :(得分:0)

如果您要查找恰好6个月的日期,这也可以使用。

示例:

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