Sql server 2008 使用T-sqldateadd和DATEDIFF函数
我试图理解的代码是,有人在计算日期时错误地实现了以下要求: 导出的JE_ACCTNG_DT设置为等于创建和发送提要时当年上个月的最后一天。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月
例如,如果本年度为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
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())