Agrupar por date y hora, ignorar la parte del time

¿Es posible escribir una consulta de Microsoft SQL que se agrupe por un tipo de datos de datetime y datetime , pero ignorando la parte del time, como la hora y el minuto?

Si está en SQL Server 2008, esto es simple.

 GROUP BY CAST(YourCol AS Date) 

Para versiones anteriores puedes usar

 GROUP BY DATEDIFF(DAY, 0, YourCol) 

Sin embargo, ninguno de estos podrá aprovechar el hecho de que un índice en YourCol que está orderado por datetime y datetime también se orderará por date y, por lo tanto, utilizará un agregado de YourCol sin una operación de sorting.

En SQL Server 2008+, puede considerar la indexing (date,time) lugar de la datetime y datetime para facilitar este tipo de consultas.

Ya sea simplemente almacenándolo como dos componentes separados y posiblemente proporcionando una columna calculada que recombina las partes (una datetime2 se almacena igual que una date y una time para que no consum más espacio, excepto si la columna adicional presiona NULL_BITMAP en un nuevo byte).

 CREATE TABLE T ( YourDateCol date, YourTimeCol time, YourDateTimeCol AS DATEADD(day, DATEDIFF(DAY,0,YourDateCol), CAST(YourTimeCol AS DATETIME2(7))) /*Other Columns*/ ) 

O, alternativamente, puede almacenarlo combinado en la tabla base y hacer que los índices usen columnas calculadas que lo dividan.

Un ejemplo de este enfoque

 CREATE TABLE T ( DT DATETIME2, D AS CAST(DT AS DATE), T AS CAST(DT AS TIME) ) CREATE INDEX IX1 ON T(DT); SELECT COUNT(*), CAST(DT AS DATE) FROM T GROUP BY CAST(DT AS DATE) CREATE INDEX IX2 ON T(D,T); SELECT COUNT(*), CAST(DT AS DATE) FROM T GROUP BY CAST(DT AS DATE) DROP TABLE T 

enter image description here

Si tiene una tabla grande y quiere que la agrupación ocurra rápidamente , no puede confiar en la agrupación de una expresión.

Cree una columna de date y hora adicional en su tabla y solicite que la complete un desencadenador que calcule la date base de su date "real":

 UPDATE MyTable SET EffectiveDate = DATEADD(DAY, 0, DATEDIFF(DAY, 0, t.RecordDate)) FROM MyTable t INNER JOIN inserted i ON i.RowID = t.RowID 

Luego coloque un índice en EffectiveDate y la agrupación (y búsqueda) será mucho más rápida.