septembre
2013
Trouver le numéro de la semaine d’une date donnée est un besoin qui revient régulièrement lorsque l’on en vient à gérer des données temporelles. Si au premier abord cela semble trivial, la fonction DATEPART pourrait bien vous réserver quelques surprises si vous n’y prenez pas garde (comme cela a été mon cas aujourd’hui).
Il ne s’agit pas ici de faire un descriptif détaillé de la fonction DATEPART. Pour cela, il y a la MSDN.
Intéressons-nous donc à l’argument WEEK. Comme on peut s’y attendre, l’utilisation de cette argument nous renvoi un numéro de semaine. Mais déjà un piège pointe le bout de son nez.
Selon la MSDN :
When datepart is week (wk, ww) or weekday (dw), the return value depends on the value that is set by using SET DATEFIRST.
Traduction :
Lorsque le paramètre est week (wk, ww) ou weekday (dw), le résultat dépend de la valeur définie par l’instruction SET DATEFIRST.
En effet, SET DATEFIRST permet de signaler à SQL SERVER quel est le premier jour d’une semaine.
En pratique, qu’est-ce que cela signifie ?
Voyons un cas concret. Pour nous faciliter la vie, créons une table de dates toute simple dont voici le code DDL ainsi que le code d’insertion de quelques lignes :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | CREATE TABLE T_DATE_DAT( DAT_DATE DATE PRIMARY KEY ); GO INSERT INTO T_DATE_DAT VALUES ('20120101'), ('20120102'), ('20120103'), ('20120104'), ('20120105'), ('20120106'), ('20120107'), ('20120108'), ('20120109'), ('20120110') |
Sur base de ceci, nous pouvons maintenant faire quelques tests. Par défaut, le premier jour d’une semaine pour SQL SERVER est le dimanche.
Exécutons alors la requête suivante :
1 2 3 4 5 | SELECT DAT_DATE, DATEPART(WEEK,DAT_DATE) AS 'WEEK' FROM T_DATE_DAT |
Vous devriez obtenir comme résultat que la première semaine de 2012 va du 1 Janvier au 7 Janvier. Le premier étant un dimanche et le 7 un samedi.
Ce n’est pas vraiment ce nous attentions n’est-ce pas ?
Signalons maintenant à SQL SERVER que le premier jour d’une semaine est le lundi et exécutons à nouveau cette requête.
1 2 3 4 5 6 7 | SET DATEFIRST 1; SELECT DAT_DATE, DATEPART(WEEK,DAT_DATE) AS 'WEEK' FROM T_DATE_DAT |
A présent, nos semaines commencent bien le lundi. C’est déjà un net progrès ! Cependant, si je regarde un calendrier sur lequel sont notés les numéros des semaines, je constate que la première semaine de 2012 commence en fait le 2 Janvier ! Cela s’explique par le fait que la première semaine d’une année est la semaine comprenant le premier jeudi de la-dite année. La première semaine de 2012 est donc bien la semaine allant du 2 Janvier au 8 Janvier.
N.B. : Cette numérotation n’est principalement utilisée qu’en Europe.
Et c’est là qu’est le piège. S’il est normal d’avoir des années de 53 semaines, l’utilisation de la fonction DATEPART avec l’argument WEEK vous retourna des semaines avec un numéro 54.
Mais alors comment faire pour récupérer le bon numéro de semaine avec la fonction DATEPART. Et bien tout simplement en n’utilisant pas l’argument WEEK mais ISOWK. Et oui, il fallait le savoir, il y a un argument pour récupérer le numéro de la semaine au format ISO.
Remplaçons donc le paramètre WEEK par ISOWK dans notre requête. Cela donne donc la requête suivante :
1 2 3 4 5 | SELECT DAT_DATE, DATEPART(ISOWK,DAT_DATE) AS 'ISO WEEK' FROM T_DATE_DAT |
Et nous récupérons maintenant les numéros de semaines correctes tels que nous les retrouvons sur tous calendriers (européens) qui se respecte.