Settimana ISO vs Settimana SQL Server


33

Ok, quindi ho un rapporto che fa un confronto tra questa settimana e la scorsa settimana e i nostri clienti hanno notato che i loro dati erano "funky". A seguito di ulteriori indagini, abbiamo scoperto che non stava facendo settimane correttamente secondo gli standard ISO. Ho eseguito questo script come test case.

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

Durante l'esecuzione ho ottenuto questi risultati.

ResultSet

Ho pensato che fosse strano e così ho fatto qualche altro scavo e ho scoperto che SQL Server conta il 1 ° gennaio come la prima settimana dell'anno in cui ISO conta la prima domenica di gennaio come la prima settimana dell'anno.

La domanda finisce per essere duplice. Domanda 1: perché? Domanda 2: c'è un modo per cambiarlo, quindi non devo modificare tutto il mio codice per usarlo ISO_Weekovunque?

Risposte:


27

Quando SQL Server implementò per la prima volta la WEEKdata / parte, dovevano fare una scelta. Non credo che ci fosse davvero molta consapevolezza al riguardo, tranne che per allinearsi allo standard più comune al momento - ricorda che questo era in un momento in cui il rispetto degli standard non era una priorità assoluta (altrimenti non avremmo cose come timestamp, IDENTITYe TOP). In seguito hanno aggiunto ISO_WEEK(credo 2008) perché nel frattempo la soluzione alternativa era quella di scrivere il tuo UDF scalare lento, schifoso, anzi, ne hanno persino creato uno davvero brutto e inserito nella documentazione ufficiale (da allora è stato rimosso fino a quel momento come posso dire).

Non conosco un modo per far DATEPART(WEEKfinta che sia DATEPART(ISO_WEEK- penso che dovrai cambiare il codice (e se stai usando il controllo del codice sorgente, questo non dovrebbe essere molto difficile - quanti posti stai eseguendo questo calcolo? hai pensato di compilarlo da qualche parte in modo che il tuo codice non debba essere crivellato con esso? Dal momento che stai cambiando il codice ora, potrebbe essere il momento di considerare questo ...).

E se vuoi davvero la risposta al perché? Penso che dovrai prendere alcuni degli sviluppatori originali per determinare perché hanno scelto il default che hanno fatto. Ancora una volta, penso che non sia stato un vero "F gli standard!" scelta, ma piuttosto "Quali standard?"

Ci sono alcune informazioni qui che potrebbero essere utili:

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


Tecnicamente tutto ciò che dovrei fare è cambiare la mia tabella DimCalendar sfortunatamente i nostri sviluppatori hanno deciso di non usarlo in diverse istanze di report, quindi viene calcolato al volo. In generale questo è stato più un esercizio di curiosità che qualsiasi tipo di crisi.
Zane,

5
Suggerirei ai tuoi sviluppatori di aggiornare i loro rapporti per seguire le migliori pratiche piuttosto che la codifica da cowboy. Ma sono solo io.
Aaron Bertrand

1
La buona notizia è che tra meno di una settimana non saranno più i miei sviluppatori. :)
Zane,

2

Esistono diverse autorità che presuppongono condizioni diverse per la prima settimana dell'anno. Alcuni presumono che il primo giorno della settimana inizi la prima settimana, ma l'idea più comune è che la prima settimana che ha il primo giovedì è la prima settimana dell'anno.

Quindi ISO_WEEKaccetta quello e come nel 2010, 2011 o 2012 come puoi verificare che ISO_WEEKdice che il 1 ° gennaio è la 52 ° o 53 ° settimana mentre WEEKo WKo WWdice che sono la prima settimana.

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.