Ok, então eu tenho um relatório que faz uma comparação desta semana x semana passada e nosso cliente notou que seus dados eram "descolados". Após uma investigação mais aprofundada, descobrimos que não estava fazendo semanas corretamente de acordo com os padrões ISO. Eu executei este script como um caso de teste.
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')
Ao executar, obtive esses resultados.
Achei que isso era peculiar e então pesquisei mais um pouco e descobri que o SQL Server conta 1º de janeiro como a primeira semana do ano, onde a ISO conta o primeiro domingo de janeiro como a primeira semana do ano.
A questão então acaba sendo dupla. Pergunta 1 por que isso? Pergunta 2 existe alguma maneira de mudar isso para não ter que modificar todo o meu código para usar ISO_Week
em todos os lugares?
Quando o SQL Server implementou pela primeira vez a
WEEK
data/parte, eles tiveram que fazer uma escolha. Eu não acho que havia muita consciência sobre isso, exceto para alinhar com o padrão mais comum na época - lembre-se que isso foi em uma época em que a conformidade com os padrões não era uma prioridade (senão não teríamos coisas comotimestamp
,IDENTITY
eTOP
). Mais tarde, eles adicionaramISO_WEEK
(2008, eu acredito) porque a solução alternativa nesse meio tempo era escrever seu próprio UDF escalar lento e ruim - na verdade, eles até criaram um muito ruim e o colocaram na documentação oficial (já foi removido até agora como posso dizer).Não conheço uma maneira de
DATEPART(WEEK
fingir que éDATEPART(ISO_WEEK
- acho que você terá que alterar o código (e se estiver usando o controle de origem, isso não deve ser muito difícil - em quantos lugares você está realizando esse cálculo? você pensou em computá-lo em algum lugar para que seu código não tenha que ser crivado com ele? Já que você está alterando o código agora, talvez seja a hora de considerar isso...).E se você realmente quer a resposta para o porquê? Acho que você terá que pegar alguns dos desenvolvedores originais para determinar por que eles escolheram o padrão que escolheram. Mais uma vez, acho que não foi um verdadeiro "F os padrões!" escolha, mas sim, "Que padrões?"
Há algumas informações aqui que podem ser úteis:
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
Existem várias autoridades assumindo condições diferentes para a primeira semana do ano. Alguns assumem que o primeiro dia da semana começa na primeira semana, mas a ideia mais comum é que a primeira semana que tem a primeira quinta-feira é a primeira semana do ano.
Então
ISO_WEEK
aceita isso e como em 2010, 2011 ou 2012 como você pode verificar queISO_WEEK
diz que 1º de janeiro é a 52ª ou 53ª semana enquantoWEEK
ouWK
ouWW
diz que é a primeira semana.