2015-05-28 54 views
0

我試圖根據原始值創建幾個日期變量,但是與當前年份。唯一的代碼,我可以運行似乎過於複雜,讓我不準確的結果:SQL DATEFROMPARTS - 在YEAR上失敗(GETDATE())

, 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.

+4

'MONTH(o.AnnualReviewDate)-1' - 如果月份是一月份會怎樣? – LittleBobbyTables

+0

導致錯誤的值是什麼? –

+0

導致錯誤的值是YEAR(GETDATE())或YEAR(@Now)。如果我使用YEAR(o.AnnualReviewDate),它運行良好,但這對解決方案沒有幫助。 –

回答

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日,所以你可以看到什麼是計算了它(你應該經常思考的要求是什麼,這樣的日期,並將其納入樣本數據)


這裏神奇的是使用這種表達日期的一年到當前復位,不影響月和日(除02月29日):

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

內表達(DATEDIFF)是「有多少自以來已經過了一年的界限「。然後,外在表達將AnnualReviewDate的全年相同數量相加。請注意,如果AnnualReviewDate是未來的日期,則該表達式甚至可以工作。

+0

感謝您對包含例外的評論。我考慮過它們,但沒有想到將它們和它們的結果包括在我的示例中。我會記住這一點。 –

0

你不應該在一個DATETIME計算中使用整數運算。做到這一點,而不是:

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