简短的回答:我怀疑这是你想要的:
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
在该表达式中还有一些日期函数的含义,以及这种日期函数如何变得复杂的感觉.通过检查第二天是否在另一个日历月中来查看Dated是否是该月的最后一天的情况.如果是这样,我们提取月中的日期并减去那么多天以跳回到上个月的最后一天. (月份从一开始不是零.所以例如,从前一个月的第17个土地向后计算17天.)否则它使用常规dateadd(月,-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)
它依赖于以下事实:当被视为隐式转换为datetime时,date -1是1900年1月1日之前的一天,根据需要确实恰好是31天的月份. (请注意,中间的-1是常规算术而不是日期值.)我想大多数人会建议你小心那个,因为我不确定当微软弃用功能时它是否可以保证.未来.