operaciones - ¿Cuál es la forma óptima de comparar fechas en el servidor Microsoft SQL?
operaciones con fechas sql (4)
Aquí hay un ejemplo:
Tengo una tabla de orden con un campo DateTime llamado OrderDate. Quiero recuperar todos los pedidos en los que la fecha del pedido sea igual al 01/01/2006. Hay siguientes maneras de hacerlo:
1) WHERE DateDiff(dd, OrderDate, ''01/01/2006'') = 0
2) WHERE Convert(varchar(20), OrderDate, 101) = ''01/01/2006''
3) WHERE Year(OrderDate) = 2006 AND Month(OrderDate) = 1 and Day(OrderDate)=1
4) WHERE OrderDate LIKE ''01/01/2006%''
5) WHERE OrderDate >= ''01/01/2006'' AND OrderDate < ''01/02/2006''
Se encuentra here
Tengo un campo datetime
SQL en una tabla muy grande. Está indexado y necesita ser consultado.
El problema es que SQL siempre almacena el componente de tiempo (aunque siempre es medianoche), pero las búsquedas son al día, en lugar de a la hora.
declare @dateVar datetime = ''2013-03-11;
select t.[DateColumn]
from MyTable t
where t.[DateColumn] = dateVar;
No devolverá nada, ya que t.[DateColumn]
siempre incluye un componente de tiempo.
Mi pregunta es ¿cuál es la mejor manera de evitar esto?
Parece que hay dos grupos principales de opciones:
Cree una segunda variable usando
dateadd
y use unabetween ... and
o>= ... and ... <=
.Convierta la
t.[DateColumn]
en un componente de solo fecha. Creo que esto hará que se ignoren los índices.
Ambas cosas parecen muy desordenadas: realmente no quiero hacer una comparación de rango o escanear la tabla.
¿Hay alguna manera mejor?
Si una de estas opciones es la mejor manera, ¿cómo y por qué?
La conversión a una DATE
o el uso de un intervalo de fechas abierto en cualquier caso dará el mejor rendimiento. Para su información, convertir a la fecha utilizando un índice son los mejores rendimientos. Más pruebas de diferentes técnicas en el artículo: ¿Cuál es la forma más eficiente de recortar el tiempo desde datetime? Publicado por Aaron Bertrand
De ese artículo:
DECLARE @dateVar datetime = ''19700204'';
-- Quickest when there is an index on t.[DateColumn],
-- because CONVERT can still use the index.
SELECT t.[DateColumn]
FROM MyTable t
WHERE = CONVERT(DATE, t.[DateColumn]) = CONVERT(DATE, @dateVar);
-- Quicker when there is no index on t.[DateColumn]
DECLARE @dateEnd datetime = DATEADD(DAY, 1, @dateVar);
SELECT t.[DateColumn]
FROM MyTable t
WHERE t.[DateColumn] >= @dateVar AND
t.[DateColumn] < @dateEnd;
También de ese artículo: usar BETWEEN
, DATEDIFF
o CONVERT(CHAR(8)...
son todos más lentos.
Obtener elementos cuando la fecha es entre fromdate y toDate.
donde convertir (fecha, fecha de vencimiento, 103) <= ''2016-07-26'' y convertir (fecha, fecha de vencimiento, 103)> = ''2016-07-26''
Podría agregar una columna calculada que incluya solo la fecha sin la hora. Entre las dos opciones, BETWEEN
operador BETWEEN
porque es ''más limpio'' para mí y debería hacer un mejor uso de los índices. La comparación de los planes de ejecución parecería indicar que BETWEEN
sería más rápido; sin embargo, en las pruebas reales se realizó lo mismo.