我试图理解在计算日期时有人错误地执行以下要求的代码:
派生的JE_ACCTNG_DT设置为等于创建和发送Feed时当前年份的前一个月的最后一天。
例如,如果当前年份是2013年,则JE_ACCTNG_DT将根据发送订阅源的季度进行以下操作:
我看到有人实现了这样的代码,如果将日期时间结果转换为日期数据类型(时间部分被删除),它似乎给出了需求中给出的示例的正确答案
DECLARE @FEED_DT datetime
SET @FEED_DT = '4/1/2013'
select DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@FEED_DT),0))
SET @FEED_DT = '7/1/2013'
select DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@FEED_DT),0))
--2013-06-30 23:59:59.000
SET @FEED_DT = '10/1/2013'
select DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@FEED_DT),0))
--2013-09-30 23:59:59.000
SET @FEED_DT = '1/1/2014'
select DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@FEED_DT),0))
--2013-09-30 23:59:59.000
令我困惑的是DATEDIFF函数接受以下参数:datepart和两个日期
DATEDIFF(datepart,startdate,enddate)
如果您注意到上述情况,则代码会将日期部分设置为“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
答案 0 :(得分:2)
鉴于此:
select DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@FEED_DT),0)
)
让我们一次拿一件......
DATEDIFF(m,0,@FEED_DT)
...计算从日期值零(评估为1-1-1900)到日期时间字段@FEED_DT中开始的日期值的整数整数月数。假设这个值是@ElapsedMonthsSinceZero并将此变量替换为原始的嵌套函数,给出:
选择DATEADD(s,-1,DATEADD(mm,@ ElapsedMonthsSinceZero,0))
现在让我们评估一下这个部分:
DATEADD(mm, @ElapsedMonthsSinceZero,0)
这会将相同的月份添加到日期“零”,即1-1-1900,这会将您带到@FEED_DT日期的第一天。基本上,我们到目前为止所做的是计算从日期0开始经过的整个月数,从第1天到月份之间的任何一天都被截断。这给了我们@FirstDayOfFEED_DT。将其替换为函数给我们......
select DATEADD(s,-1,@FirstDayOfFEED_DT)
现在我们有了@FEED_DT日期的第一天,减去1给了我们上一个月的最后一天。
我想我只是因为传递了0而不是日期的差异而被抛弃了。
答案 1 :(得分:1)
假设您在新列中添加了几天,并且您有一个参数@date的存储过程,并且您希望将当前日期添加到该参数并以天为单位获取结果。
DateAdd(days,@date,Getdate())