Semana ISO vs Semana del Servidor SQL


33

Bien, tengo un informe que hace una comparación esta semana contra la semana pasada y nuestro cliente notó que sus datos eran "originales". Tras una investigación adicional, descubrimos que no funcionaba correctamente de acuerdo con las normas ISO. Ejecuté este script como un caso de prueba.

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

Cuando corrí obtuve estos resultados.

Conjunto resultante

Pensé que esto era peculiar, así que investigué un poco más y descubrí que SQL Server cuenta el 1 de enero como la primera semana del año, donde ISO cuenta el primer domingo de enero como la primera semana del año.

La pregunta entonces termina siendo doble. Pregunta 1 ¿por qué es esto? Pregunta 2 ¿hay alguna forma de cambiar esto para que no tenga que modificar todo mi código para usarlo en ISO_Weektodas partes?

Respuestas:


27

Cuando SQL Server implementó por primera vez la WEEKfecha / parte, tuvieron que tomar una decisión. No creo que haya mucha conciencia al respecto, excepto para alinearnos con el estándar más común en ese momento: recuerde que esto fue en un momento en que cumplir con los estándares no era una prioridad principal (de lo contrario, no tendríamos cosas como timestamp, IDENTITYy TOP). Más tarde agregaron ISO_WEEK(creo que en 2008) porque mientras tanto la solución era escribir su propio UDF escalar lento, horrible, de hecho, incluso crearon uno realmente malo y lo pusieron en la documentación oficial (desde entonces se ha eliminado hasta ahora como puedo decir)

No conozco una forma de DATEPART(WEEKfingir que es así DATEPART(ISO_WEEK: creo que tendrá que cambiar el código (y si está utilizando el control de origen, esto no debería ser muy difícil: ¿en cuántos lugares está realizando este cálculo? ¿pensaste en calcularlo en algún lugar para que tu código no tenga que estar plagado de él? Ya que estás cambiando el código ahora, este podría ser el momento de considerar esto ...).

¿Y si realmente quieres la respuesta a por qué? Creo que tendrá que tomar algunos de los desarrolladores originales para determinar por qué eligieron el valor predeterminado que hicieron. Una vez más, creo que no fue un verdadero "F los estándares!" elección, sino más bien, "¿Qué estándares?"

Aquí hay información que puede ser útil:

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


Técnicamente, todo lo que debería hacer es cambiar mi tabla DimCalendar, desafortunadamente nuestros desarrolladores decidieron no usarla en varias instancias de informes, por lo que se calcula sobre la marcha. En general, esto fue más un ejercicio de curiosidad que cualquier tipo de crisis.
Zane

55
Sugeriría que sus desarrolladores actualicen sus informes para seguir las mejores prácticas en lugar de la codificación de vaqueros. Pero solo soy yo.
Aaron Bertrand

1
La buena noticia es que en menos de una semana ya no serán mis desarrolladores. :)
Zane

2

Hay varias autoridades que asumen condiciones diferentes para la primera semana del año. Algunos suponen que el primer día de la semana comienza la primera semana, pero la idea más común es que la primera semana que tiene el primer jueves es la primera semana del año.

Por lo tanto ISO_WEEKacepta que y al igual que en 2010, 2011 o 2012 como se puede comprobar que ISO_WEEKdice 1 ª enero es 52ª o 53ª semana mientras WEEKo WKo WWdice que son la primera semana.

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.