Redondeo de SQL DateTime a medianoche

81

Tengo un pequeño problema con mi consulta SQL. Estoy usando la función GETDATE, sin embargo, digamos que ejecuto la secuencia de comandos a las 5 p.m., obtendrá registros entre el 12/12/2011 5 p.m. y el 18/12/2011 5 p.m. ¿Cómo puedo hacer que muestre los registros de todo el 12/12/2011 - 18/12/2011 básicamente ignorar el tiempo?

Mi guión:

WHERE Orders.OrderStatus = 'Shipped'  
AND Orders.ShipDate > (GETDATE()-6)  
henryaaron
fuente

Respuestas:

114

En SQL Server 2008 y versiones posteriores, puede convertir el DateTimea a Date, lo que elimina el elemento de tiempo.

WHERE Orders.OrderStatus = 'Shipped'  
AND Orders.ShipDate >= (cast(GETDATE()-6 as date))  

En SQL Server 2005 y versiones anteriores, puede usar:

WHERE Orders.OrderStatus = 'Shipped'  
AND Orders.ShipDate >= DateAdd(Day, Datediff(Day,0, GetDate() -6), 0)
DaveShaw
fuente
1
Obtuve este tipo de fecha no es un tipo de sistema definido.
henryaaron
2
Supongo que no estás usando SQL 2008 entonces :)
DaveShaw
@ user1090389 es por eso que puse la opción de conversión de cadenas; D
Bassam Mehanni
@DaveShaw - Falta un DATEADD allí
MatBailie
Lo siento @Dems Dave parece menos complicado
henryaaron
54

Aquí está la cosa más simple que he encontrado

-- Midnight floor of current date

SELECT Convert(DateTime, DATEDIFF(DAY, 0, GETDATE()))

DATEDIFF devuelve el número entero de días antes o desde 1900-1-1, y Convert Datetime lo devuelve amablemente a esa fecha a la medianoche.

Dado que DateDiff devuelve un número entero, puede usar sumar o restar días para obtener el desplazamiento correcto.

SELECT Convert(DateTime, DATEDIFF(DAY, 0, GETDATE()) + @dayOffset)

Esto no es redondear esto es truncar ... Pero creo que eso es lo que se pregunta. (Para redondear, agregar uno y truncar ... y eso tampoco es redondear, que el techo, pero nuevamente lo más probable es que lo que quieras. Para realmente redondear, agrega .5 (¿funciona?) Y truncar.

Resulta que puede agregar .5 a GetDate () y funciona como se esperaba.

-- Round Current time to midnight today or midnight tomorrow

SELECT Convert(DateTime, DATEDIFF(DAY, 0, GETDATE() + .5))

Hice todas mis pruebas en SQL Server 2008, pero creo que estas funciones también se aplican a 2005.

Darrel Lee
fuente
Esto funciona en 2k5 solo lo probé. where [ScanDate] >= convert(datetime, datediff(day, 0, getdate())) and [ScanDate] < convert(datetime, datediff(day, -1, getdate()))
nulltron
9
--
-- SQL DATEDIFF getting midnight time parts 
--
SELECT GETDATE() AS Now, 
   Convert(DateTime, DATEDIFF(DAY, 0, GETDATE())) AS MidnightToday,
   Convert(DateTime, DATEDIFF(DAY, -1, GETDATE())) AS MidnightNextDay,
   Convert(DateTime, DATEDIFF(DAY, 1, GETDATE())) AS MidnightYesterDay
go
Now                   MidnightToday          MidnightNextDay        MidnightYesterDay     
 --------------------  ---------------------  ---------------------  --------------------- 
 8/27/2014 4:30:22 PM  8/27/2014 12:00:00 AM  8/28/2014 12:00:00 AM  8/26/2014 12:00:00 AM 
edvox1138
fuente
5
SELECT getdate()

Resultado: 2012-12-14 16: 03: 33.360

SELECT convert(datetime,convert(bigint, getdate()))

Resultado 2012-12-15 00: 00: 00.000

Jeremy Atkinson
fuente
1
Gracias por la respuesta. Lo que estaba tratando de resaltar es que el conversor a bigint y viceversa hace el redondeo por usted.
Jeremy Atkinson
1
Este código lo redondea hasta la medianoche al final del día si la hora es posterior al mediodía, lo que hace que esto sea incorrecto durante la mitad del día.
ChrisM
El uso de este método puede causar impactos en el rendimiento más adelante con conjuntos de datos más grandes.
Taco タ コ ス
3

Como mencionó @BassamMehanni, puede transmitir como FECHA en SQL Server 2008 en adelante ...

SELECT
  *
FROM
  yourTable
WHERE
      dateField >= CAST(GetDate() - 6 AS DATE)
  AND dateField <  CAST(GetDate() + 1 AS DATE)

La segunda condición puede ser justa GetDate(), pero estoy mostrando este formato como un ejemplo Less Than DateXpara evitar tener que convertir el campo de fecha en una FECHA también, mejorando así enormemente el rendimiento.


Si estás en 2005 o menos, puedes usar esto ...

SELECT
  *
FROM
  yourTable
WHERE
      dateField >= DATEADD(DAY, DATEDIFF(DAY, 0, GetDate()) - 6, 0)
  AND dateField <  DATEADD(DAY, DATEDIFF(DAY, 0, GetDate()) + 1, 0)
MatBailie
fuente
3

Intente usar esto.

WHERE Orders.OrderStatus = 'Shipped'  
AND Orders.ShipDate >= CONVERT(DATE, GETDATE())
UttamG
fuente
1

Esto puede parecer barato pero me está funcionando

SELECT CONVERT (DATETIME, LEFT (CONVERT (VARCHAR, @ dateFieldOrVariable, 101), 10) + '00: 00: 00.000')

Jean-Louis Gervais
fuente
1

Puede convertir la fecha y hora en una fecha y luego volver a una fecha y hora. Esto restablecerá la marca de tiempo.

seleccione getdate () --2020-05-05 13: 53: 35.863

seleccione emitir (emitir (GETDATE () como fecha) como fecha y hora) --2020-05-05 00: 00: 00.000
Ben
fuente
0

Yo suelo hacer

SELECT *
FROM MyTable
WHERE CONVERT(VARCHAR, MyTable.dateField, 101) = CONVERT(VARCHAR, GETDATE(), 101)

si está utilizando SQL SERVER 2008, puede hacer

SELECT *
FROM MyTable
WHERE CAST(MyTable.dateField AS DATE) = CAST(GETDATE() AS DATE)

Espero que esto ayude

Bassam Mehanni
fuente
3
Si usa el primer ejemplo, destruye la capacidad del optimizador para usar índices, etc. Usar funciones de cadena para hacer aritmética de fechas y comparaciones es una muy mala idea. Ni siquiera debería mencionarse (en mi opinión), es una opción tan pobre.
MatBailie
No tiene que hacerlo si está utilizando SQL Server 2008, de lo contrario, no estoy seguro de qué otra manera podría hacerlo en SQL Server 2000/2005, se agradecería un ejemplo, gracias.
Bassam Mehanni
Para ser justo. Ambas opciones destruyen la capacidad del optmizer para usar índices. Debe realizar una funcionalidad en la columna de predicado de filtro. Esto incluye yesos.
pim
0

Podría redondear el tiempo.

El uso a ROUNDcontinuación lo redondeará a la medianoche.

WHERE Orders.OrderStatus = 'Shipped'  
AND Orders.ShipDate >  CONVERT(datetime, (ROUND(convert(float, getdate()-6.5),0)))
Aceite
fuente