web-dev-qa-db-fra.com

Semaine ISO contre Semaine SQL Server

D'accord, j'ai donc un rapport qui fait une comparaison cette semaine par rapport à la semaine dernière et notre client a remarqué que leurs données étaient "géniales". Après une enquête plus approfondie, nous avons constaté qu'il ne faisait pas correctement les semaines selon les normes ISO. J'ai exécuté ce script comme cas de test.

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

Lors de l'exécution, j'ai obtenu ces résultats.

ResultSet

Je pensais que c'était particulier et j'ai donc creusé un peu plus et j'ai constaté que SQL Server comptait le 1er janvier comme la première semaine de l'année, alors que l'ISO comptait le premier dimanche de janvier comme la première semaine de l'année.

La question finit alors par être double. Question 1 pourquoi est-ce? La question 2 existe-t-il un moyen de changer cela, je n'ai donc pas à modifier tout mon code pour utiliser ISO_Week partout?

34
Zane

À l'époque où SQL Server a implémenté la date/partie WEEK pour la première fois, ils ont dû faire un choix. Je ne pense pas qu'il y avait vraiment beaucoup de conscience à ce sujet, sauf pour s'aligner sur la norme la plus courante à l'époque - rappelez-vous que c'était à une époque où la conformité aux normes n'était pas une priorité absolue (sinon nous n'aurions pas des choses comme timestamp, IDENTITY et TOP). Ils ont ensuite ajouté ISO_WEEK (2008 je crois) parce que la solution de contournement en attendant était d'écrire votre propre UDF scalaire lente et merdique - en fait, ils en ont même créé un très mauvais et l'ont mis dans la documentation officielle (il a depuis été supprimé pour autant que Je peux dire).

Je ne connais pas de moyen de faire DATEPART(WEEK faites comme si c'était DATEPART(ISO_WEEK - Je pense que vous devrez changer le code (et si vous utilisez le contrôle de code source, cela ne devrait pas être très difficile - combien d'endroits effectuez-vous ce calcul? Avez-vous pensé à le calculer quelque part pour que votre code ne fonctionne pas? t être criblé avec elle? Puisque vous changez le code maintenant, ce pourrait être le moment de considérer cela ...).

Et si vous voulez vraiment la réponse à pourquoi? Je pense que vous devrez saisir certains des développeurs originaux pour déterminer pourquoi ils ont choisi la valeur par défaut qu'ils fait. Encore une fois, je pense que ce n'était pas un vrai "F les normes!" choix, mais plutôt, "Quelles normes?"

Il y a ici quelques informations qui peuvent être utiles:

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

27
Aaron Bertrand

Plusieurs autorités assument des conditions différentes pour la première semaine de l'année. Certains supposent que le premier jour de la semaine commence la première semaine, mais l'idée la plus courante est que la première semaine qui a le premier jeudi est la première semaine de l'année.

Donc ISO_WEEK accepte cela et comme en 2010, 2011 ou 2012 car vous pouvez vérifier que ISO_WEEK indique que le 1er janvier correspond à la 52e ou 53e semaine tandis que WEEK ou WK ou WW indique qu'il s'agit de la première semaine.

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
2
Sedat GÖÇTÜ