Tydzień ISO a Tydzień SQL Server

33

Okej, więc mam raport, który porównuje ten tydzień do zeszłego tygodnia, a nasz klient zauważył, że ich dane były „funky”. Po dalszym dochodzeniu ustaliliśmy, że tygodnie nie przebiegały prawidłowo zgodnie ze standardami ISO. Uruchomiłem ten skrypt jako przypadek testowy.

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')

Po uruchomieniu otrzymałem te wyniki.

ResultSet

Pomyślałem, że to dziwne, więc zacząłem więcej kopać i odkryłem, że SQL Server liczy 1 stycznia jako pierwszy tydzień roku, a ISO liczy pierwszą niedzielę stycznia jako pierwszy tydzień roku.

Pytanie kończy się podwójnie. Pytanie 1 dlaczego to jest? Pytanie 2 czy jest jakiś sposób, aby to zmienić, więc nie muszę modyfikować całego mojego kodu, aby używać go ISO_Weekwszędzie?

Zane
źródło

Odpowiedzi:

27

Kiedy SQL Server po raz pierwszy wdrożył WEEKdatę / część, musieli dokonać wyboru. Nie sądzę, żeby było w tym naprawdę dużo świadomości, z wyjątkiem dostosowania się do najpopularniejszych wówczas standardów - pamiętajcie, że było to w czasie, gdy zgodność ze standardami nie była najwyższym priorytetem (inaczej nie mielibyśmy takich rzeczy jak timestamp, IDENTITYi TOP). Później dodali ISO_WEEK(wydaje mi się, że w 2008 r.), Ponieważ w międzyczasie obejściem tego problemu było napisanie własnego, powolnego, gównianego skalarnego UDF - w rzeczywistości nawet stworzyli naprawdę zły i umieścili go w oficjalnej dokumentacji (od tego czasu został usunięty do tej pory jak mogę powiedzieć).

Nie znam sposobu na DATEPART(WEEKudawanie, że tak jest DATEPART(ISO_WEEK- myślę, że będziesz musiał zmienić kod (a jeśli używasz kontroli źródła, nie powinno to być bardzo trudne - ile miejsc wykonujesz te obliczenia? myślałeś o tym, aby go gdzieś obliczyć, aby Twój kod nie musiał być z nim związany? Ponieważ teraz zmieniasz kod, może to być czas na rozważenie tego ...).

A jeśli naprawdę chcesz uzyskać odpowiedź na pytanie, dlaczego? Myślę, że będziesz musiał pobrać kilku oryginalnych programistów, aby ustalić, dlaczego wybrali domyślną wersję. Ponownie myślę, że to nie był faktyczny „F standardy!” wybór, a raczej „Jakie standardy?”

Jest tu kilka informacji, które mogą być przydatne:

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

Aaron Bertrand
źródło
Technicznie wszystko, co powinienem zrobić, to zmienić tabelę DimCalendar, niestety nasi programiści postanowili nie używać jej w kilku instancjach raportów, więc jest ona obliczana na bieżąco. Zasadniczo było to raczej ćwiczenie ciekawości niż jakikolwiek kryzys.
Zane
5
Sugeruję, aby programiści zaktualizowali swoje raporty, aby postępowali zgodnie z najlepszymi praktykami, a nie kodowaniem kowbojskim. Ale to tylko ja.
Aaron Bertrand
1
Dobra wiadomość jest za niecały tydzień, że nie będą już moimi programistami. :)
Zane
2

Istnieje kilka organów przyjmujących różne warunki w pierwszym tygodniu roku. Niektórzy zakładają, że pierwszy dzień tygodnia rozpoczyna się w pierwszym tygodniu, ale najczęstszym pomysłem jest to, że pierwszy tydzień, który ma pierwszy czwartek, jest pierwszym tygodniem roku.

Tak ISO_WEEKzgadza się, że i tak jak w 2010, 2011 lub 2012, jak można sprawdzić, czy ISO_WEEKmówi 01 stycznia jest 52-ty lub 53-gi tygodniu podczas WEEKlub WKlub WWmówi, że są w pierwszym tygodniu.

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
Sedat GÖÇTÜ
źródło