SQL DATEFROMPARTS - 年失败(GETDATE())

时间:2015-05-28 12:57:16

标签: sql-server date

我正在尝试根据原始值创建多个日期变量,但是使用当前年份。我可以运行的唯一代码似乎过于复杂,并给我不准确的结果:

, DATEADD(DAY,DATEPART(DAYOFYEAR, o.AnnualReviewDate),
  DATEADD(YEAR,YEAR(GETDATE())-1900,0)) AS ARDateCurr
DATEADD(DAY,DATEPART(DAYOFYEAR, o.AnnualReviewDate)+30,
  DATEADD(YEAR,YEAR(GETDATE())-1900,0)) AS ARDatePlus30

为什么:

DECLARE @Now AS DATE = GETDATE()
DECLARE @Year AS INT = DATEPART(YEAR,@Now)
...
, DATEFROMPARTS(YEAR(@Now),MONTH(o.AnnualReviewDate)-1,
DAY(o.AnnualReviewDate)) AS ARDateMin30

给我错误信息:

'无法构造数据类型日期,某些参数的值无效。'

Here's an example of what I'm getting now - you can see that the days of the month are off.

2 个答案:

答案 0 :(得分:0)

您不应在DATETIME计算中使用整数运算。这样做:

DATEFROMPARTS(YEAR(@Now),MONTH(DATEADD(M,-1,o.AnnualReviewDate)),DAY(o.AnnualReviewDate)) AS ARDateMin30

答案 1 :(得分:0)

猜测,这些是您正在寻找的价值:

declare @t table (AnnualReviewDate datetime)
insert into @t (AnnualReviewDate) values
('20121004'),('20090924'),('20101007'),('20141008'),('20090508'),
('20120229')

select
    AnnualReviewDate,
    r.ARCurrDue,
    DATEADD(day,-30,ARCurrDue) as ARDateMin30,
    DATEADD(day,30,ARCurrDue) as ARDatePlus30
from @t t
cross apply (SELECT DATEADD(year,DATEDIFF(year,AnnualReviewDate,GETDATE())
             ,AnnualReviewDate) as ARCurrDue) r

结果:

AnnualReviewDate        ARCurrDue               ARDateMin30             ARDatePlus30
----------------------- ----------------------- ----------------------- -----------------------
2012-10-04 00:00:00.000 2015-10-04 00:00:00.000 2015-09-04 00:00:00.000 2015-11-03 00:00:00.000
2009-09-24 00:00:00.000 2015-09-24 00:00:00.000 2015-08-25 00:00:00.000 2015-10-24 00:00:00.000
2010-10-07 00:00:00.000 2015-10-07 00:00:00.000 2015-09-07 00:00:00.000 2015-11-06 00:00:00.000
2014-10-08 00:00:00.000 2015-10-08 00:00:00.000 2015-09-08 00:00:00.000 2015-11-07 00:00:00.000
2009-05-08 00:00:00.000 2015-05-08 00:00:00.000 2015-04-08 00:00:00.000 2015-06-07 00:00:00.000
2012-02-29 00:00:00.000 2015-02-28 00:00:00.000 2015-01-29 00:00:00.000 2015-03-30 00:00:00.000

也就是说,ARCurrDue应该与AnnualReviewDate的日期和月份相同,但是在当前年份中,其他列的距离是正负30天?

您注意到我在样本中包含了2月29日,因此您可以看到为此计算的内容(您应该始终考虑这些日期的要求并将其包括在内)样本数据)

这里的神奇之处在于使用这个表达式将日期的年份重置为当前日期,而不会影响月份和日期(2月29日除外):

DATEADD(year,DATEDIFF(year,AnnualReviewDate,GETDATE())
       ,AnnualReviewDate)

内在表达式(DATEDIFF)是"自AnnualReviewDate"以来已经过了多少年边界。外表达式然后将相同数量的整年添加到AnnualReviewDate。请注意,如果AnnualReviewDate是将来的日期,则此相同的表达式甚至可以使用。