Compare DATETIME y DATE ignorando la porción de tiempo

151

Tengo dos tablas donde [date]es el tipo de columna DATETIME2(0).

Tengo que comparar dos registros solo por sus partes de fecha (día + mes + año), descartando partes de tiempo (horas + minutos + segundos).

¿Cómo puedo hacer eso?

abatishchev
fuente

Respuestas:

252

Use el CASTnuevo DATEtipo de datos en SQL Server 2008 para comparar solo la parte de la fecha:

IF CAST(DateField1 AS DATE) = CAST(DateField2 AS DATE)
marc_s
fuente
61

Un pequeño inconveniente en la respuesta de Marc es que ambos campos de fecha se han encasillado, lo que significa que no podrá aprovechar ningún índice.

Por lo tanto, si es necesario escribir una consulta que pueda beneficiarse de un índice en un campo de fecha, entonces es necesario el siguiente enfoque (bastante complicado).

  • El campo de fecha indexado (llámelo DF1) no debe ser tocado por ningún tipo de función.
  • Por lo tanto, debe comparar DF1 con el rango completo de valores de fecha y hora para el día de DF2.
  • Eso es desde la parte de fecha de DF2, hasta la parte de fecha del día posterior a DF2.
  • Es decir (DF1 >= CAST(DF2 AS DATE)) AND (DF1 < DATEADD(dd, 1, CAST(DF2 AS DATE)))
  • NOTA : Es muy importante que la comparación sea > = (igualdad permitida) a la fecha de DF2 y (estrictamente) < el día después de DF2. Además, el operador ENTRE no funciona porque permite la igualdad en ambos lados.

PD: Otra forma de extraer la fecha solamente (en versiones anteriores de SQL Server) es usar un truco de cómo se representa internamente la fecha.

  • Echa la fecha como un flotador.
  • Truncar la parte fraccional
  • Convertir el valor a una fecha y hora
  • Es decir CAST(FLOOR(CAST(DF2 AS FLOAT)) AS DATETIME)
Desilusionado
fuente
5

Aunque voté por la respuesta marcada como correcta. Quería tocar algunas cosas para cualquiera que se tope con esto.

En general, si está filtrando específicamente solo los valores de fecha . Microsoft recomienda usar el formato de idioma neutral de ymdo y-m-d.

Tenga en cuenta que el formulario '2007-02-12' se considera neutral en cuanto al idioma solo para los tipos de datos DATE, DATETIME2 y DATETIMEOFFSET.

Hacer una comparación de fechas usando el enfoque antes mencionado es simple. Considere el siguiente ejemplo artificial.

--112 is ISO format 'YYYYMMDD'
declare @filterDate char(8) = CONVERT(char(8), GETDATE(), 112)

select 
    * 
from 
    Sales.Orders
where
    CONVERT(char(8), OrderDate, 112) = @filterDate

En un mundo perfecto, debe evitarse cualquier manipulación de la columna filtrada porque esto puede evitar que SQL Server use índices de manera eficiente. Dicho esto, si los datos que está almacenando solo se refieren a la fecha y no a la hora, considere almacenarlos como DATETIMEa la medianoche como la hora. Porque:

Cuando SQL Server convierte el literal al tipo de columna filtrada, supone la medianoche cuando no se indica una parte de tiempo. Si desea que dicho filtro devuelva todas las filas de la fecha especificada, debe asegurarse de almacenar todos los valores con la medianoche como la hora.

Por lo tanto, suponiendo que solo le interese la fecha y almacene sus datos como tal. La consulta anterior se puede simplificar a:

--112 is ISO format 'YYYYMMDD'
declare @filterDate char(8) = CONVERT(char(8), GETDATE(), 112)

select 
    * 
from 
    Sales.Orders
where
    OrderDate = @filterDate
pimbrouwers
fuente
3

Puedes probar este

CONVERT(DATE, GETDATE()) = CONVERT(DATE,'2017-11-16 21:57:20.000')

Lo pruebo para MS SQL 2014 siguiendo el código

select case when CONVERT(DATE, GETDATE()) = CONVERT(DATE,'2017-11-16 21:57:20.000') then 'ok'
            else '' end
reza.cse08
fuente
-3

Para Comparar dos fechas como MM / DD / AAAA a MM / DD / AAAA . Recuerde El primer tipo de columna de campo debe ser dateTime. Ejemplo: columnName: payment_date dataType: DateTime .

después de eso puedes compararlo fácilmente. La consulta es:

select  *  from demo_date where date >= '3/1/2015' and date <=  '3/31/2015'.

Es muy simple ...... Lo probó .....

pankaj
fuente
Esto no responde a la pregunta. Se consulta durante un mes, no un día.
Curtis Yallop
Para su consulta de marzo: si la fecha es '3/31/2015' a las 13:00, no se encontrará. Debe usar <'4/1/2015'.
Curtis Yallop
También considere usar el formato de fecha internacional '2015-03-01'. En Canadá (y en muchos otros lugares), un formato oficial es DD / MM / AAAA que hace que ambos formatos sean ambiguos y problemáticos.
Curtis Yallop
Esta respuesta no trata con 2 tablas, como se solicitó en la pregunta.
Curtis Yallop
Sí im acuerdo, pero soy sólo demostrando solución no solución internacional .. usted tiene que cambiar un poco de orden ...
Pankaj