J'essaie de sélectionner des enregistrements d'aujourd'hui et le même jour de chaque semaine pour les 4 dernières semaines.
J'ai besoin que cela soit lié à la date actuelle car je vais exécuter cette requête tous les jours, donc je ne veux pas utiliser un entre ou quelque chose où je spécifie manuellement la plage de dates.
Tout ce que j'ai trouvé ou essayé jusqu'à présent a extrait le dernier mois de données mais pas les 4 dernières semaines du même jour de la semaine.
Data from 7/10/2019 Data from 7/3/2019 Data from 6/26/2019 Data from 6/19/2019
Cela fonctionne mais extrait tout de le mois dernier.
Si la date d'aujourd'hui est 7/10/2019 j'ai besoin
select * from table where thedatecolumn >= DATEADD(mm, -1, GETDATE())
Chaque jour, je vais exécuter ce requête, donc j'ai besoin qu'elle soit dynamique en fonction de la date actuelle.
3 Réponses :
Vous pouvez essayer d'utiliser un cte récursif qui commence aujourd'hui et soustrait à plusieurs reprises 7 jours - vous vous assurez ainsi de toujours atterrir le même jour de la semaine. En suivant un exemple:
WITH cteFromToday AS( SELECT 0 AS WeeksBack, GETDATE() AS MyDate UNION ALL SELECT WeeksBack + 1 AS WeeksBack, DATEADD(d, -7, MyDate) AS MyDate FROM cteFromToday ) SELECT TOP 5 * FROM cteFromToday OPTION ( MaxRecursion 0 );
Je pense que vous voulez regarder 21 jours en arrière, puis filtrer les dates qui ont le même jour de la semaine:
select * from table
where thedatecolumn >= DATEADD(DAY, -21, CAST(GETDATE() AS DATE))
and DATEPART(WEEKDAY, thedatecolumn) = DATEPART(WEEKDAY, GETDATE())
@data_stephen J'ai modifié ma réponse après avoir réalisé que vous ne voulez des données que pour les quatre dates tombant le même jour de la semaine.
C'est génial et simple. Merci beaucoup!
Autant que je sache, l'utilisation de fonctions sur les colonnes vous empêche d'utiliser des index. Vous pouvez observer de faibles performances de cette requête pour les grandes tables. Il vaut mieux éviter de telles solutions lorsque les performances sont pertinentes.
@Lukasz Je crois que vous trouverez que la limite inférieure sur 21 jours est complètement sargable.
C'est assez simple. Remplacez CURRENT_TIMESTAMP ici pour une date donnée.
SELECT something WHERE datetimecolumn >= CONVERT(DATE,CURRENT_TIMESTAMP) AND datetimecolumn < DATEADD(DAY,1, CONVERT(DATE,CURRENT_TIMESTAMP)) -- Todays range, OR datetimecolumn >= DATEADD(DAY,-7,CONVERT(DATE,CURRENT_TIMESTAMP)) AND datetimecolumn < DATEADD(DAY,1,DATEADD(DAY,-7,CONVERT(DATE,CURRENT_TIMESTAMP)))-- LastWeek , OR datetimecolumn >= DATEADD(DAY,-14,CONVERT(DATE,CURRENT_TIMESTAMP)) AND datetimecolumn < DATEADD(DAY,1,DATEADD(DAY,-14,CONVERT(DATE,CURRENT_TIMESTAMP)))-- TwoWeeksAgo, OR datetimecolumn >= DATEADD(DAY,-21,CONVERT(DATE,CURRENT_TIMESTAMP)) AND datetimecolumn < DATEADD(DAY,1, DATEADD(DAY,-21,CONVERT(DATE,CURRENT_TIMESTAMP))) -- ThreeWeeksAgo
SO, si vous souhaitez obtenir des données pour un ensemble de plages pour une journée entière avec ces dates: p >
SELECT CONVERT(DATE,CURRENT_TIMESTAMP) AS Today, DATEADD(DAY,-7,CONVERT(DATE,CURRENT_TIMESTAMP)) AS LastWeek , DATEADD(DAY,-14,CONVERT(DATE,CURRENT_TIMESTAMP)) AS TwoWeeksAgo, DATEADD(DAY,-21,CONVERT(DATE,CURRENT_TIMESTAMP)) AS ThreeWeeksAgo
Mark, merci beaucoup. Cela renvoie exactement les mêmes résultats à shawnt00, mais comme j'inclus cela dans une requête plus grande, il se peut que j'aie encore besoin de 2 options pour le faire. Très appréciée.
"Aujourd'hui (mardi)" Aujourd'hui, c'est mercredi / jeudi (selon l'endroit où vous vous trouvez géographiquement, mais où est UTC -21 pour que ce soit mardi), vous êtes donc toujours après les données de mardi, indépendamment le jour est-il vraiment?
Obtenez minuit d'aujourd'hui, puis utilisez ENTRE minuit ET {minuit + 23h59m59s}. Ajoutez ENTRE {minuit-7j} ET {minuit-7j + 23h59m59s}. Et ainsi de suite pour les semaines restantes.
@ ŁukaszNojek - il y a des valeurs en dehors de cette plage en raison des valeurs inférieures à une seconde. Vous avez besoin d'une date donnée> = et
Certes, ce n'était qu'une simplification dans un espace limité de commentaires. Merci pour la clarification.