Quelle est la syntaxe SQL pour créer une colonne dans ma table de dimension de date qui regroupera les dates dans ce regroupement hebdomadaire spécifique?

J'utilise SQL Server 2014 et j'ai un tableau de dimension de date (appelé DateDimension) dont l'une des colonnes est une colonne Date (appelée Date). Cette list de tableau toutes les dates du 2000-01-01 au 2017-12-31

Extrait de la colonne Date de la table DateDimension:

2000-01-01 00:00:00.000 2000-01-02 00:00:00.000 ....................... 2017-12-31 00:00:00.000 

J'ai besoin d'une nouvelle colonne (disons "Groupe de la semaine") dans cette table qui va regrouper les dates ci-dessus en utilisant la logique suivante:

Une semaine commence le lundi et se termine le dimanche. Ainsi, pour les dates entre le 3 janvier 2000 (qui est un lundi) et le 09 janvier 2000 (qui est un dimanche), la nouvelle colonne affichera "Wk 03-09 Janvier 2015" et ainsi de suite pour les dates restantes du tableau des dimensions de date .

Quel est le code T-SQL pour y parvenir?

Je suppose que votre @@datefirst correspond à dimanche. Et je suppose également que la partie de l'année et du mois correspond au jour de début de la semaine plutôt qu'au jour de la fin.

Vous pouvez utiliser cette première expression dans une update ou éventuellement même sous la forme d'une colonne, d'une fonction ou d'une vue calculée. Je ne peux pas me souvenir quelles fonctions de dates ont des problèmes avec le déterminisme en raison des parameters régionaux, donc il pourrait y avoir quelques limitations.

 concat( 'Wk ', right('0' + datename(day, dateadd(day, -((datepart(weekday, "Date") + 5) % 7), "Date")), 2), '-', right('0' + datename(day, dateadd(day, -((datepart(weekday, "Date") + 5) % 7)+6, "Date")),2), ' ', datename(month, dateadd(day, -((datepart(weekday, "Date") + 5) % 7), "Date")), ' ', datename(year, dateadd(day, -((datepart(weekday, "Date") + 5) % 7), "Date")) ) 

Comme il y a deux dates impliquées dans les calculs, vous ne pouvez pas utiliser la fonction format() aussi facilement. Voici une update deux étapes qui accomplit la même chose:

 update DateDimension set WeekGroup = format( dateadd(day, -((datepart(weekday, "Date") + 5) % 7), "Date"), 'Wk dd-XX MMMM yyyy' /* leave a placeholder */ ); update DateDimension set WeekGroup = replace( WeekGroup, 'XX', format( dateadd(day, -((datepart(weekday, "Date") + 5) % 7) + 6, "Date"), 'dd' ) ); 

Si vous aimez imbriquer les expressions, cela peut bien sûr être fait en une seule étape:

 update DateDimension set WeekGroup = replace( format( dateadd(day, -((datepart(weekday, "Date") + 5) % 7), "Date"), 'Wk dd-XX MMMM yyyy' /* leave a placeholder */ ), 'XX', format( dateadd(day, -((datepart(weekday, "Date") + 5) % 7) + 6, "Date"), 'dd' ) ); 

Les maths ne sont vraiment pas si compliqués:

Pour find le début d'une "semaine" pour chaque date, nous voulons déterminer combien de jours depuis le lundi précédent. Lundi est compté comme le jour de la semaine # 2 (quand @@datefirst est défini sur dimanche), donc nous voulons en déduire deux de la numérotation "régulière" du jour de la semaine et la faire revenir à la semaine précédente. Pour éviter les nombres négatifs dans l'arithmétique modulaire, il suffit d'append 5 (ce qui est congru à -2 mod 7). Cette même expression est réutilisée pour calculer toutes les différentes parties de date.

EDIT: Dans un commentaire, vous avez laissé entendre que vous devez avoir un format légèrement différent pour les semaines qui s'étendent sur un mois (ce qui pourrait inclure des années aussi).

Cela peut être géré avec une expression de case . J'espère que vous avez l'idée générale et vous pouvez voir où faire des ajustements pour le format que vous aimeriez voir appliqué entre les deux cas.

 update DateDimension set WeekGroup = case when month(dateadd(day, -((datepart(weekday, "Date") + 5) % 7), "Date")) = month(dateadd(day, -((datepart(weekday, "Date") + 5) % 7) + 6, "Date")) then replace( format( dateadd(day, -((datepart(weekday, "Date") + 5) % 7), "Date"), 'Wk dd-XX MMMM yyyy' /* leave a placeholder */ ), 'XX', format( dateadd(day, -((datepart(weekday, "Date") + 5) % 7) + 6, "Date"), 'dd' ) ) else concat( format( dateadd(day, -((datepart(weekday, "Date") + 5) % 7), "Date"), 'Wk dd MMMM yyyy-' ), format( dateadd(day, -((datepart(weekday, "Date") + 5) % 7) + 6, "Date"), 'dd MMMM yyyy' ) ) end;