SQL Server: получите дату на недели ISO - PullRequest
0 голосов
/ 29 августа 2018

Провёл лучшую половину дня, пытаясь выяснить это.

Я хочу получить datediff двух дат, основываясь на их неделе ISO .

Вот мой код:

SET DATEFIRST 1 ;   

DECLARE @A date, @B date;

SET @A = '20180829'; -- August 29th
SET @B = '20180902'; -- September 2nd

SELECT DATEDIFF(WW, @A, @B )

Если вы проверите: http://whatweekisit.org/ (Неделя 35, год 2018), вы увидите, что он работает с 27 августа до 2 сентября .

Приведенный выше код вернет DateDiff = 1, которое должно быть 0. Попытка запустить DateDiff на неделе ISO просто возвращает следующую ошибку:

datepart iso_week не поддерживается функцией date с датой

Я пытался извлечь даты недели из дат, но затем у меня возникает проблема при сравнении дат из разных лет.

Есть ли способ обойти это?

Ответы [ 3 ]

0 голосов
/ 29 августа 2018

Итак, после некоторого прочтения, нет собственного способа сделать это. Но вот обходной путь:

DECLARE @A DATE = '20180829' -- August 29th
DECLARE @B DATE = '20180902' -- September 2nd

--We need to back each date up to the first day of its week.
DECLARE @A_FIRSTWEEKDAY DATE = DATEADD(DAY, -(DATEPART(WEEKDAY, @A) - 1), @A)
DECLARE @B_FIRSTWEEKDAY DATE = DATEADD(DAY, -(DATEPART(WEEKDAY, @B) - 1), @B)

/*The WEEKDAY part counts Sunday as day 1. If the original date was
a Sunday, it backed up zero days and it still needs to back up six
days. If it was any other day, it backed all the way up to Sunday
and now it needs to move forward one day.*/
IF DATEPART(WEEKDAY, @A) = 1
     BEGIN SET @A_FIRSTWEEKDAY = DATEADD(DAY, -6, @A_FIRSTWEEKDAY) END
ELSE BEGIN SET @A_FIRSTWEEKDAY = DATEADD(DAY,  1, @A_FIRSTWEEKDAY) END
IF DATEPART(WEEKDAY, @B) = 1 
     BEGIN SET @B_FIRSTWEEKDAY = DATEADD(DAY, -6, @B_FIRSTWEEKDAY) END
ELSE BEGIN SET @B_FIRSTWEEKDAY = DATEADD(DAY,  1, @B_FIRSTWEEKDAY) END

--Now we can just difference the weeks.
SELECT DATEDIFF(DAY, @A_FIRSTWEEKDAY, @B_FIRSTWEEKDAY) / 7
0 голосов
/ 29 августа 2018

Это связано с тем, что DATEDIFF всегда использует воскресенье в качестве первого дня недели для обеспечения детерминистической работы функции: https://docs.microsoft.com/datediff-transact-sql

То есть 20180902 (воскресенье) - первый день следующей недели.

0 голосов
/ 29 августа 2018
SELECT DATEDIFF(ww, DATEADD(dd,-1, @A ), DATEADD(dd,-1,@B)) 
--Seems to do the trick?

Взято из: Количество недель и неполных недель между двумя днями, вычислено неправильно

Хотя я не понимаю, почему другой пост в ссылке добавляет 1 в конце.

...