SQL Server参数日期范围问题

时间:2018-10-02 09:55:13

标签: sql-server tsql sql-server-2008 datetime

我正在使用以下查询来获取两个日期之间的差额。日期范围为每12个月收费一次。

CY代表当前年份,而PY代表上一年。当前年份中的日期用于计算上一年的日期

当我执行查询时,我得到以下输出,其中月份为11和364。但是我希望月份为12,日期为365或(leap年为366)。

DECLARE @CY_StartDate date =CAST(DATEADD(MONTH, DATEDIFF(MONTH, -1, GETDATE())-13, 0) AS DATE), 
        @CY_EndDate date =CAST(DATEADD(MONTH, DATEDIFF(MONTH, -1, GETDATE())-1, -1) AS DATE);    --- Rolling 12 months
DECLARE @PY_startDate date =DATEADD(YEAR,-1,@CY_StartDate),
        @PY_EndDate date =DATEADD(YEAR,-1,@CY_EndDate)

SELECT
        @CY_StartDate AS CY_Start,
        @CY_EndDate AS CY_End,
        @PY_StartDate AS PY_Start,
        @PY_EndDate AS PY_End,
        DATEDIFF(year, @CY_StartDate, @CY_EndDate) AS yr,
        DATEDIFF(month, @CY_StartDate, @CY_EndDate) AS month,
        DATEDIFF(day, @CY_StartDate, @CY_EndDate) AS day

电流输出

CY_Start     CY_End         PY_Start     PY_End     yr  month   day
2017-10-01   2018-09-30     2016-10-01  2017-09-30  1   11      364

预期产量

CY_Start     CY_End         PY_Start     PY_End     yr  month   day
2017-10-01   2018-09-30     2016-10-01  2017-09-30  1   12      365

2 个答案:

答案 0 :(得分:3)

您所获得的价值是有道理的。 DATEDIFF计算2个日期之间的滴答声,其中滴答声是第一个参数的值。因此,例如:DATEDIFF(MONTH, '20180101','20180228')将返回1,因为仅发生了1个滴答(2 - 1 = 1)。似乎在这里,您只需要添加1:

DECLARE @CY_StartDate date =CAST(DATEADD(MONTH, DATEDIFF(MONTH, -1, GETDATE())-13, 0) AS DATE), 
        @CY_EndDate date =CAST(DATEADD(MONTH, DATEDIFF(MONTH, -1, GETDATE())-1, -1) AS DATE);    --- Rolling 12 months
DECLARE @PY_startDate date =DATEADD(YEAR,-1,@CY_StartDate),
        @PY_EndDate date =DATEADD(YEAR,-1,@CY_EndDate)

        select
        @CY_StartDate as CY_Start,
        @CY_EndDate AS CY_End,
        @PY_StartDate AS PY_Start,
        @PY_EndDate AS PY_End,

        DATEDIFF(year,@CY_StartDate,DATEADD(DAY,1,@CY_EndDate)) as yr,
        DATEDIFF(month,@CY_StartDate,DATEADD(DAY,1,@CY_EndDate)) as month,
        DATEDIFF(day,@CY_StartDate,DATEADD(DAY,1,@CY_EndDate)) as day

我再使用DATEADD的原因是因为这使它与每个表达式都一致。 yr的值是正确的,但是,对于2017010120171231之类的日期,yr的值将是0。因此,如果日期移动,@CY_EndDate的值加上1天将使此更为可靠。

答案 1 :(得分:2)

常识。 1到10之间有多少个数字(包括两者)?您可能会说10-1 = 9是不正确的。正确答案是(10-1)+1 = 10。

同样,如果您有两个包含日期,例如2017-10-012018-09-30将一个加到DATEDIFF(DAY, '2017-10-01', '2018-09-30')以获得365而不是364。

但是,正如另一个答案中所建议的那样,结束日期排他(不计算在内)要好得多,因为它可以直接进行日期计算。在您的示例中,您应该在最后一个日期前加上1天,这样您就可以[2017-10-01, 2018-10-01)DATEDIFF产生预期的结果。