Тиждень 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')

Під час запуску я отримав ці результати.

Результат набору

Я подумав, що це своєрідно, і тому я здійснив ще одне копання і виявив, що SQL Server вважає 1 січня першим тижнем року, де ISO вважає першу неділю січня як перший тиждень року.

Потім питання стає двократним. Питання 1, чому це? Питання 2: Чи є можливість змінити це, тому мені не доведеться змінювати весь код, щоб використовувати його ISO_Weekскрізь?

Відповіді:


27

Коли ще SQL Server вперше реалізував WEEKдату / частину, їм довелося зробити вибір. Я не думаю, що про це було дуже багато свідомості, за винятком того, щоб прирівнятись до найпоширенішого на той час стандарту - пам’ятайте, це було в той час, коли відповідність стандартам не було першочерговим завданням (інакше у нас не було б таких речей, як timestamp, IDENTITYі TOP). Пізніше вони додали ISO_WEEK(я вважаю, 2008 р.), Оскільки тим часом вирішувалося написати власний, повільний, хитрий скалярний АДС - насправді вони навіть створили справді поганий і занесли це в офіційну документацію (з тих пір його видалено досі як я можу сказати).

Я не знаю, як зробити DATEPART(WEEKвигляд, що це DATEPART(ISO_WEEK- я думаю, вам доведеться змінити код (і якщо ви використовуєте управління джерелом, це не повинно бути дуже складним - у скільки місць ви виконуєте цей розрахунок? ви думали про те, щоб десь його обчислити, щоб ваш код не мав бути з ним позбавлений? Оскільки зараз ви змінюєте код, можливо, саме час розглянути це ...).

І якщо ви дійсно хочете відповіді на те, чому? Я думаю, вам доведеться схопити деяких оригінальних розробників, щоб визначити, чому вони обрали типовий за замовчуванням. Знову ж таки, я думаю, що це були не фактичні "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
Хороша новина пройде менше ніж за тиждень, вони більше не стануть моїми розробниками. :)
Зейн

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.