Неделя ISO против Недели SQL Server

33

Итак, у меня есть отчет, который сравнивает эту неделю с прошлой, и наши клиенты заметили, что их данные были «фанки». После дальнейшего расследования мы обнаружили, что в соответствии со стандартами ISO он неделями работал неправильно. Я запустил этот скрипт как тестовый пример.

SET DATEFIRST 1
SELECT DATEPART(WEEK, '3/26/13')
    , DATEPART(WEEK, '3/27/12')
    , DATEPART(WEEK, '3/20/12')
    , DATEPART(WEEK, '1/2/12')
SELECT DATEPART(ISO_WEEK, '3/26/13')
    , DATEPART(ISO_WEEK, '3/27/12')
    , DATEPART(ISO_WEEK, '3/20/12')
    , DATEPART(ISO_WEEK, '1/2/12')

При запуске я получил эти результаты.

ResultSet

Я подумал, что это необычно, поэтому я провел еще несколько копаний и обнаружил, что SQL Server считает 1 января первой неделей года, когда ISO считает первое воскресенье января первой неделей года.

Тогда вопрос оказывается в два раза. Вопрос 1 почему это? Вопрос 2 есть ли способ изменить это, поэтому мне не нужно изменять весь мой код для использования ISO_Weekвезде?

Зейн
источник

Ответы:

27

Назад, когда SQL Server впервые реализовал WEEKдату / часть, им пришлось сделать выбор. Я не думаю, что было действительно много сознания об этом, за исключением того, чтобы соответствовать наиболее распространенному стандарту в то время - помните, что это было в то время, когда соответствие стандартам не было главным приоритетом (иначе у нас не было бы таких вещей, как timestamp, IDENTITYи TOP). Позже они добавили ISO_WEEK(я полагаю, что в 2008 году), потому что обходным решением было написать свой собственный, медленный, дерьмовый скалярный UDF - фактически они даже создали действительно плохой и поместили его в официальную документацию (с тех пор он был удален до сих пор). как я могу сказать).

Я не знаю способ сделать DATEPART(WEEKвид , что это DATEPART(ISO_WEEK- я думаю , что вам придется изменить код (если вы используете систему управления версиями, это не должно быть очень трудно - сколько места вы выполнять этот расчет Have? Вы думали о том, чтобы где-то его вычислить, чтобы ваш код не нужно было с ним переплетать? Поскольку вы сейчас меняете код, возможно, пришло время подумать об этом ...).

И если вы действительно хотите получить ответ, почему? Я думаю, вам придется взять некоторых оригинальных разработчиков, чтобы определить, почему они выбрали вариант по умолчанию. Опять же, я думаю, что это не было "F стандартов!" выбор, а точнее "какие стандарты?"

Здесь есть некоторая информация, которая может быть полезна:

https://stackoverflow.com/questions/348880/getting-week-number-off-a-date-in-ms-sql-server-2005

http://blogs.lessthandot.com/index.php/DataMgmt/DataDesign/iso-week-in-sql-server

Аарон Бертран
источник
Технически все, что мне нужно сделать, это изменить мою таблицу DimCalendar, к сожалению, наши разработчики решили не использовать ее в нескольких экземплярах отчета, поэтому она рассчитывается на лету. По большому счету это было больше любопытством, чем кризисом.
Зейн
5
Я бы посоветовал вашим разработчикам обновить свои отчеты, чтобы они следовали передовым методам, а не ковбойскому кодированию. Но это только я.
Аарон Бертран
1
Хорошей новостью является то, что меньше чем через неделю они больше не будут моими разработчиками. :)
Zane
2

Есть несколько властей, предполагающих разные условия для первой недели года. Некоторые предполагают, что первый день недели начинается с первой недели, но наиболее распространенная идея заключается в том, что первая неделя с первым четвергом - это первая неделя года.

Так ISO_WEEKпризнает , что и как в 2010, 2011 или 2012 , как вы можете проверить , что ISO_WEEKговорит 1 января будет пятьдесят второй или пятьдесят третьей неделе во время WEEKили WKили WWговорит , что они в первую неделю.

SELECT DATEPART (WW,'01/01/2010')   --> 1
SELECT DATEPART (WK,'01/01/2010')   --> 1
SELECT DATEPART (WEEK,'01/01/2010')   --> 1
SELECT DATEPART (ISO_WEEK,'01/01/2010')   --> 53
Седат GÖÇTÜ
источник