¿Cómo puedo truncar una fecha y hora en SQL Server?

Resuelto Julio César asked hace 15 años • 14 respuestas

¿Cuál es la mejor manera de truncar un valor de fecha y hora (para eliminar horas, minutos y segundos) en SQL Server?

Por ejemplo:

declare @SomeDate datetime = '2009-05-28 16:30:22'
select trunc_date(@SomeDate)

-----------------------
2009-05-28 00:00:00.000
Julio César avatar May 29 '09 04:05 Julio César
Aceptado

Esto continúa reuniendo votos adicionales con frecuencia, incluso varios años después, por lo que necesito actualizarlo para las versiones modernas de Sql Server. Para Sql Server 2008 y posteriores, es sencillo:

cast(getdate() as Date)

Tenga en cuenta que los últimos tres párrafos cerca del final todavía se aplican y, a menudo, es necesario dar un paso atrás y encontrar una manera de evitar el yeso en primer lugar.

Pero también hay otras formas de lograrlo. Aquí están los más comunes.

La forma correcta (nueva desde Sql Server 2008)

cast(getdate() as Date)

La forma correcta (antigua)

dateadd(dd, datediff(dd, 0, getdate()), 0)

Esto es más antiguo ahora, pero aún vale la pena saberlo porque también puede adaptarse fácilmente a otros momentos, como el primer momento del mes, minuto, hora o año.

Esta forma correcta utiliza funciones documentadas que forman parte del estándar ANSI y cuyo funcionamiento está garantizado, pero puede ser algo más lento. Funciona encontrando cuántos días hay desde el día 0 hasta el día actual y sumando esa cantidad de días al día 0. Funcionará sin importar cómo esté datetimealmacenado y sin importar cuál sea su ubicación.

la manera rapida

cast(floor(cast(getdate() as float)) as datetime)

Esto funciona porque datetimelas columnas se almacenan como valores binarios de 8 bytes. Transmítelos a float, floorpara eliminar la fracción y la parte de tiempo de los valores desaparecerá cuando los vuelva a transmitir a datetime. Todo cambia un poco sin una lógica complicada y es muy rápido.

Tenga en cuenta que esto depende de un detalle de implementación que Microsoft puede cambiar en cualquier momento, incluso en una actualización automática del servicio. Tampoco es muy portátil. En la práctica, es muy poco probable que esta implementación cambie pronto, pero aún así es importante ser consciente del peligro si decide utilizarla. Y ahora que tenemos la opción de elegir una fecha, rara vez es necesario.

La forma incorrecta

cast(convert(char(11), getdate(), 113) as datetime)

La forma incorrecta funciona al convertir a una cadena, truncar la cadena y volver a convertirla a una fecha y hora. Está mal por dos razones:

  1. Es posible que no funcione en todas las configuraciones regionales y
  2. Se trata de la forma más lenta posible de hacer esto... y no sólo un poco; es como uno o dos órdenes de magnitud más lento que las otras opciones.

Actualización Esto ha recibido algunos votos últimamente, por lo que quiero agregar que desde que publiqué esto he visto evidencia bastante sólida de que Sql Server optimizará la diferencia de rendimiento entre la forma "correcta" y la forma "rápida". , lo que significa que ahora deberías favorecer lo primero.

En cualquier caso, desea escribir sus consultas para evitar la necesidad de hacerlo en primer lugar. Es muy raro que debas hacer este trabajo en la base de datos.

En la mayoría de los lugares, la base de datos ya es un cuello de botella. Generalmente, es el servidor al que resulta más costoso agregar hardware para mejorar el rendimiento y el más difícil de lograr esas adiciones correctamente (hay que equilibrar los discos con la memoria, por ejemplo). También es el más difícil de escalar hacia afuera, tanto desde el punto de vista técnico como empresarial; Técnicamente es mucho más fácil agregar un servidor web o de aplicaciones que un servidor de base de datos e incluso si eso fuera falso, no paga más de $20,000 por licencia de servidor para IIS o Apache.

Lo que intento señalar es que, siempre que sea posible, debes hacer este trabajo a nivel de aplicación. El único momento en el que debería encontrarse truncando un datetimeservidor Sql es cuando necesita agrupar por día, e incluso entonces probablemente debería tener una columna adicional configurada como una columna calculada, mantenida en el momento de inserción/actualización, o mantenida en lógica de aplicación. Elimine este trabajo que rompe índices y consume mucha CPU de su base de datos.

Joel Coehoorn avatar May 28 '2009 21:05 Joel Coehoorn

Sólo para SQL Server 2008

CAST(@SomeDateTime AS Date) 

Luego, vuelve a enviarlo a la fecha y hora si quieres.

CAST(CAST(@SomeDateTime AS Date) As datetime)
DJ. avatar May 28 '2009 22:05 DJ.

Solo en aras de una respuesta más completa, aquí hay una forma funcional de truncar a cualquiera de las partes de la fecha e incluir minutos (reemplace GETDATE()con la fecha para truncar).

Esto es diferente de la respuesta aceptada en que puede usar no solo dd(días), sino también cualquiera de las partes de la fecha (ver aquí ):

dateadd(minute, datediff(minute, 0, GETDATE()), 0)

Tenga en cuenta que en la expresión anterior, 0es una fecha constante al comienzo de un año (1900-01-01). Si necesita truncar a partes más pequeñas, como segundos o milisegundos, debe tomar una fecha constante que esté más cerca de la fecha que se va a truncar para evitar un desbordamiento.

Lucero avatar May 31 '2011 12:05 Lucero

El fragmento que encontré en la web cuando tuve que hacer esto fue:

 dateadd(dd,0, datediff(dd,0, YOURDATE))
 e.g.
 dateadd(dd,0, datediff(dd,0, getDate()))
Tom Ritter avatar May 28 '2009 21:05 Tom Ritter
CONVERT(DATE, <yourdatetime>) or CONVERT(DATE, GetDate()) or CONVERT(DATE, CURRENT_TIMESTAMP)
Dean avatar Nov 18 '2009 19:11 Dean