将当前值添加到将来的日期SQL

时间:2018-09-04 02:50:30

标签: sql sql-server

我正在尝试加载数据以备将来使用。我的情况是这样的,我有2016年,2017年和2018年的数据(到8月)。每年都有当前和“上一年同一天”值关联。数据汇总到月份。要求是我也使用'PYSD'值加载未来日期的数据,即从2018年9月到2019年8月的数据。例如,2017年9月的“当前”值将是2018年9月的“ PYSD”值,依此类推。当我尝试这种特殊的逻辑时,出现错误,指出“溢出”,并且我无法弄清楚是什么原因。这仅在我的WHERE子句中的第二个条件下发生。我的SELECT子句汇总了一个月的数据并输出为'08 -01-2018'-每月/每年将有一行。

SELECT 
    CAST(YEAR(DATEADD(dd, 364, CalendarDate)) AS VARCHAR(250)) 
     + '-' + RIGHT('00' + CAST(MONTH(DATEADD(dd, 364, CalendarDate)) AS VARCHAR(250)), 2) 
     + '-' + '01' AS MonthPeriod 
FROM
    DateTable 
WHERE  
    DATEADD(DD, 364, CalendarDate) > '08-31-2018' 
    AND DATEADD(DD, 364, CalendarDate) < '08-01-2019'

我的错误:

  

第1行3州16级消息517
  在“日期”列中添加值会导致溢出。

此外,如果有更简单的方法,请接受建议。我在使用SQL Server。

TIA。

添加了示例数据:

enter image description here

2 个答案:

答案 0 :(得分:2)

如您在原始问题的答案之一中所述,最大日期为9999-12-31

这意味着任何一种DATEADD(DD, 364, CalendarDate)都应该总是失败。您是否要检查2018年的日期都没关系,因为它必须先执行dateadd,这会导致溢出。

为避免溢出,请用其他方式添加日期-将实际的CalendarDate与目标日期之前一年进行比较。

CalendarDate > DATEADD(DD, -364, '08-31-2018')

或者只是

CalendarDate > '2017-08-31' 

在剩下的讨论中,我将剩下的部分指定日期,或者是否应为364,365,第一个月等。

答案 1 :(得分:1)

DateTable中的最大日期是多少?您的日期可能是9999年。因此加364将导致它溢出。它与SELECT子句

无关

在查询中,您只需执行此操作

SELECT DATEADD(MONTH, 
               DATEDIFF(MONTH, 0, 
                        DATEADD(DAY, 364, CalendarDate)), 0) AS MonthPeriod

注意: DATEADD(MONTH, DATEDIFF(MONTH, 0, <date>), 0)将为您提供每月的第一天

编辑:

发生溢出错误是因为DateTable包含日期为9999的行。向其中添加364天将导致溢出。

一种快速的解决方法是删除年份为9998或9999的那些行

另一种方法是更改​​查询,以使它不会增加CalendarDate

的天数
WHERE  CalendarDate > DATEADD(DAY, 364, '2018-08-31')
AND    CalendarDate < DATEADD(DAY, 364, '2019-08-01')

注意:我使用ISO格式YYYY-MM-DD的日期字符串。建议使用明确的日期格式。

完整的查询将是

SELECT DATEADD(MONTH, 
               DATEDIFF(MONTH, 0, 
                        DATEADD(DAY, 364, CalendarDate)), 0) AS MonthPeriod 
FROM   DateTable
WHERE  CalendarDate > DATEADD(DAY, 364, '2018-08-31')
AND    CalendarDate < DATEADD(DAY, 364, '2019-08-01')