Sql server 2008 使用T-sqldateadd和DATEDIFF函数

Sql server 2008 使用T-sqldateadd和DATEDIFF函数,sql-server-2008,tsql,Sql Server 2008,Tsql,我试图理解的代码是,有人在计算日期时错误地实现了以下要求: 导出的JE_ACCTNG_DT设置为等于创建和发送提要时当年上个月的最后一天。 例如,如果本年度为2013年,则根据发送feed的季度,JE_ACCTNG_DT将如下所示: 2013年1月4日发送的第一季度feed的JE_ACCTNG_DT=2013年3月31日 JE_ACCTNG_DT=2013年6月30日,第二季度feed于2013年7月1日发送 2013年1月10日发送的第三季度feed的JE_ACCTNG_DT=2013年9月

我试图理解的代码是,有人在计算日期时错误地实现了以下要求:

导出的JE_ACCTNG_DT设置为等于创建和发送提要时当年上个月的最后一天。
例如,如果本年度为2013年,则根据发送feed的季度,JE_ACCTNG_DT将如下所示:

  • 2013年1月4日发送的第一季度feed的JE_ACCTNG_DT=2013年3月31日
  • JE_ACCTNG_DT=2013年6月30日,第二季度feed于2013年7月1日发送
  • 2013年1月10日发送的第三季度feed的JE_ACCTNG_DT=2013年9月30日
  • 2014年1月1日发送的第四季度feed的JE_ACCTNG_DT=12/31/2013
我看到有人实现了这样的代码,如果datetime结果转换为日期数据类型(时间部分被删除),它似乎为需求中给出的示例给出了正确的答案

让我困惑的是DATEDIFF函数接受以下参数:一个datepart和两个Date

DATEDIFF(日期部分、开始日期、结束日期)

如果您注意到上面的情况,那么代码将日期部分设置为“m”,但在预期日期时,第二个参数的值为零

DECLARE @FEED_DT datetime = '4/1/2013'
DECLARE @DateAddResult as int 

SET @DateAddResult = DATEDIFF(m,0,@FEED_DT)
select @DateAddResult 
--1359
select DATEADD(s,-1,DATEADD(mm, @DateAddResult,0))
--2013-03-31 23:59:59.000
代码到底在做什么?我本以为会出错的。它是否将0值强制为日期

我认为真正的要求应该是计算上一季度的最后一天。我会这样做的

SELECT dateadd(day, -1, DATEADD(quarter,DATEDIFF(quarter,'1900/01/01', GETDATE()), '1900/01/01')) as FirstDayOfQuarter
鉴于此:

选择DATEADD(s,-1,DATEADD(mm,DATEDIFF(m,0,@FEED_DT),0)

让我们一件一件地来

DATEDIFF(m,0,@FEED_DT)
…计算从日期值0(计算为1-1-1900)到datetime字段@FEED_DT中开始的日期值的整整数月数。假设该值为@ElapsedMonthsSinceZero,并将该变量替换为原始嵌套函数,给出:

选择DATEADD(s,-1,DATEADD(mm,@ElapsedMonthsSinceZero,0))

现在让我们评估一下这一部分:

DATEADD(mm, @ElapsedMonthsSinceZero,0)
这会将相同的月数添加到日期“零”,即1-1-1900,这会将您带到日期@FEED_DT当月的第一天。基本上,到目前为止,我们所做的是计算从日期0开始经过的月份总数,将第1天之后的任何一天截断为月份。这给了我们@FirstDayOfFEED\u DT。将其替换为函数会给我们

select DATEADD(s,-1,@FirstDayOfFEED_DT)
现在我们有了日期@FEED_DT当月的第一天,减去1就得到了上个月的最后一天


我想我只是被传递的值是0而不是日期的差异搞糊涂了

假设您在一个新列中添加了几天,并且有一个参数@date的存储过程,您希望将当前日期添加到该参数中,并以天为单位获得结果

 DateAdd(days,@date,Getdate())

也请停止使用懒惰的速记,如mm和m。如果您是指月份,请键入
month
。同意m和mm。你两条评论加起来给了我答案。谢谢。还有几件事:将
0
更改为
'19000101'
,这样它就不会模棱两可和令人困惑了。停止使用这种愚蠢的“减去一秒”的伎俩。这很危险。如果你要执行大量的日期范围查询,请阅读全文。不要再考虑季度的最后一天。想想下一个季度的第一天,它总是更容易计算,所有数据类型都将在>=本季度开始和<下季度开始时正常工作。我假设您使用的是基于标记的SQL Server 2008,但万一您有权访问2012,请签出新的EOMonth函数。
 DateAdd(days,@date,Getdate())