2010-07-20 11 views
11

Estoy trabajando en la creación de un gráfico para mi cliente y ellos quieren obtener el conteo total de los clientes durante un período de 24 horas, 3 días, 1 semana, 1 mes, etc. Honestamente, no soy el mejor con SQL, por lo que generar estas consultas no es mi fuerte.¿Cuál es la mejor manera de obtener los últimos resultados de 24 horas en T-SQL?

En lo que respecta a obtener los clientes más de 24 horas, he encontrado dos declaraciones de "dónde" que pueden funcionar, pero no estoy seguro de cuál es la mejor.

Primera versión:

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

Segunda versión:

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

La primera versión genera 21 filas y el segundo genera 17 filas (desde el mismo conjunto de datos, por supuesto), de modo obviamente, uno es más preciso que el otro. Me estoy inclinando hacia el primero, pero me gustaría su opinión ... por favor.

Gracias, Andrew

+0

creo que 'DONDE DATEDIFF (hh, CreatedDate, GETDATE())> 24' necesita ser' DONDE DATEDIFF (hh, CreatedDate, GETDATE()) < –

+1

24'. ... o más exactamente, 'WHERE DATEDIFF (hh, CreatedDate, GETDATE()) <= 24' para que coincida con la lógica del segundo :) –

Respuesta

8

Evitar la primera versión. Primero, porque desactiva la utilización del índice. El segundo problema (funcional) con la primera versión es DATEDIFF(HOUR...) devuelve todos los valores de menos de 25 horas. Prueba esto para mayor claridad:

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

Tal vez estos para cada una de sus cláusulas donde?

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) 

Y como Flo mencionado acerca de los índices, sólo asegúrese de que está indexación de su columna CreatedDate.

8

La primera versión no es precisa.

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

Esto devolverá los valores en algún lugar entre desde hace 23.0001 horas a 24,9999 horas hace porque usted está contando "límites cruzados", no un período real de 24 horas. Tenga en cuenta que de 1:59:59 a 2:00:00 es solo un segundo, pero DateDiff por horas devolverá 1 hora. Del mismo modo, 1:00:00 a 2:59:59 es casi 2 horas, pero DateDiff por horas devuelve la misma 1 hora.

La segunda versión es correcta.

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

Adición de 24 horas a la fecha actual producirá una vez, hace exactamente 24,0 horas, a la milésima de segundo. Esto devolverá 24 horas de datos.

Además, la primera versión sería mala incluso si fuera lo que querías porque el motor tendría que realizar cálculos matemáticos en cada fila de la tabla completa, haciendo inútil cualquier índice potencial y consumiendo un montón de CPU innecesaria. En su lugar, haga los cálculos en el lado opuesto de la expresión del nombre de la columna.Para duplicar la lógica de su primera expresión sin la penalización en el rendimiento se vería así:

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

Ejemplo:

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

y probar esto es lo mismo que tu primera expresión:

  • DateDiff(hh, '20100719 17:00', '20100720 17:52') = 24
Cuestiones relacionadas