Проблемы с диапазоном дат параметров SQL Server - PullRequest
0 голосов
/ 02 октября 2018

Я использую следующий запрос, чтобы получить разницу между двумя датами.Диапазон дат - 12-месячный интервал.

CY означает Текущий год, а PY - Предыдущий.Даты в текущем году используются для вычисления дат предыдущего года

Когда я выполняю свой запрос, у меня есть следующий вывод, где месяц равен 11, а день 364. Но я хочу, чтобы мои месяцы были двенадцатью, а день365 или (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 голосов
/ 02 октября 2018

здравый смысл.Сколько существует чисел от 1 до 10, включая оба?Вы можете сказать, что есть 10 - 1 = 9, что неверно.Правильный ответ (10 - 1) + 1 = 10.

Аналогично, если у вас есть две включающие даты, например, 2017-10-01 и 2018-09-30, вы добавляете одну к DATEDIFF(DAY, '2017-10-01', '2018-09-30'), чтобы получить 365 вместо 364.

Однако, как предлагается в другом ответе, гораздо лучше до конечной даты исключить (не считать), что делает расчеты даты прямыми.В вашем примере вы должны добавить 1 день к последней дате, чтобы у вас было [2017-10-01, 2018-10-01) и DATEDIFF даст желаемые результаты.

0 голосов
/ 02 октября 2018

Значения, которые вы получаете, имеют смысл.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 было правильным, однако для таких дат, как 20170101 и 20171231, значение yr будет 0.Следовательно, добавление 1 дня к значению @CY_EndDate делает это намного более надежным, если даты сдвигаются.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...