2010-07-20 5 views
11

Je travaille sur la création d'un tableau pour mon client et il veut obtenir le nombre total de clients sur une période de 24 heures, 3 jours, 1 semaine, 1 mois, etc. Je ne suis honnêtement pas le meilleur avec SQL, donc générer ces requêtes n'est pas mon fort. En ce qui concerne l'obtention des clients pendant plus de 24 heures, j'ai trouvé deux énoncés «où» qui peuvent fonctionner, mais je ne suis pas sûr de savoir lequel est le meilleur.Quel est le meilleur moyen d'obtenir les dernières 24 heures de résultats dans T-SQL?

Première version:

WHERE DATEDIFF(hh,CreatedDate,GETDATE())>24 

seconde version:

WHERE CreatedDate >= DATEADD(HH, -24, GETDATE()) 

La première version génère des 21 rangées et la seconde génère des 17 lignes (à partir du même ensemble de données, bien entendu), de sorte évidemment, l'un est plus précis que l'autre. Je penche pour la première, mais j'aimerais avoir votre avis ... s'il vous plaît.

Merci, Andrew

+0

Je pense que 'WHERE DATEDIFF (hh, CreatedDate, GETDATE())> 24' doit être' WHERE DATEDIFF (hh, CreatedDate, GETDATE()) <24' –

+1

. ..ou plus précisément, 'WHERE DATEDIFF (hh, CreatedDate, GETDATE()) <= 24' pour correspondre à la logique de la seconde :) –

Répondre

8

Évitez la première version. D'abord, parce que cela désactive l'utilisation de l'index. Le deuxième problème (fonctionnel) avec la première version est, DATEDIFF(HOUR...) renvoie toutes les valeurs inférieures à 25 heures. Essayez ceci pour plus de clarté:

SELECT DATEDIFF(HOUR, '2010-07-19 00:00:00', '2010-07-20 00:59:59.99') 
1

Peut-être que ce soit pour chacune de vos clauses where?

WHERE CreatedDate < GETDATE() AND CreatedDate >= DATEADD(hh, -24, GETDATE) 

WHERE CreatedDate < GETDATE() AND CreatedDate >= DATEADD(day, -3, GETDATE) 

WHERE CreatedDate < GETDATE() AND CreatedDate >= DATEADD(wk, -1, GETDATE) 

WHERE CreatedDate < GETDATE() AND CreatedDate >= DATEADD(mm, -1, GETDATE) 

Et comme flo mentionné à propos des index, assurez-vous que vous indexez votre colonne CreatedDate.

8

La première version n'est pas exacte.

WHERE DateDiff(hh, CreatedDate, GETDATE()) > 24 

Cela renverra quelque part entre les valeurs d'il y a il y a à 24,9999 heures 23.0001 heures parce que vous comptez « limites croisés », pas une période de 24 heures réelle. Considérer que de 1:59:59 à 2:00:00 est seulement une seconde, mais DateDiff par heures retournera 1 heure. De même, 1:00:00 à 2:59:59 est presque 2 heures, mais DateDiff par heures renvoie le même 1 heure.

La deuxième version est correcte.

WHERE CreatedDate >= DateAdd(hh, -24, GETDATE()) 

Ajout 24 heures à la date actuelle donnera un temps il y a exactement 24,0 heures, à la milliseconde. Cela va donc retourner 24 heures de données. De plus, la première version serait mauvaise même si c'était ce que vous vouliez parce que le moteur devrait effectuer des calculs de date sur chaque rangée de la table entière, rendant inutile tout indice potentiel et consommant un tas de CPU inutiles. Au lieu de cela, faites le calcul sur le côté opposé de l'expression du nom de la colonne.Pour dupliquer la logique de votre première expression sans la pénalité de performance ressemblerait à ceci:

WHERE CreateDate >= DateAdd(hh, DateDiff(hh, 0, GETDATE()) - 24, 0) 

Exemple:

  • GetDate() = '20100720 17:52'
  • DateDiff(hh, 0, '20100720 17:52') = 969065
  • DateAdd(hh, 969065 - 24, 0) = '20100719 17:00'

et prouver c'est la même chose que ta première expression:

  • DateDiff(hh, '20100719 17:00', '20100720 17:52') = 24
Questions connexes