Aquí está el problema que estoy teniendo: Tengo una consulta de gran tamaño que se necesita comparar datetimes en la cláusula where para ver si dos fechas están en el mismo día. Mi solución actual, que aspira, es el envío de los datetimes en una UDF para convertirlos a la medianoche del mismo día, y después comprobar esas fechas para la igualdad. Cuando se trata el plan de consulta, esto es un desastre, al igual que casi todas las UDF en las combinaciones o donde cláusulas. Este es uno de los únicos lugares en mi solicitud que no he sido capaz de erradicar a las funciones y dar al optimizador de consultas de algo que en realidad se puede utilizar para localizar el mejor índice.¿Qué es una buena manera de comprobar si dos datetimes están en el mismo día calendario en TSQL?
En este caso, no es práctico volver a combinar el código de función en la consulta.
Creo que me falta algo simple aquí.
Aquí está la función de referencia.
if not exists (select * from dbo.sysobjects
where id = object_id(N'dbo.f_MakeDate') and
type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
exec('create function dbo.f_MakeDate() returns int as
begin declare @retval int return @retval end')
go
alter function dbo.f_MakeDate
(
@Day datetime,
@Hour int,
@Minute int
)
returns datetime
as
/*
Creates a datetime using the year-month-day portion of @Day, and the
@Hour and @Minute provided
*/
begin
declare @retval datetime
set @retval = cast(
cast(datepart(m, @Day) as varchar(2)) +
'/' +
cast(datepart(d, @Day) as varchar(2)) +
'/' +
cast(datepart(yyyy, @Day) as varchar(4)) +
' ' +
cast(@Hour as varchar(2)) +
':' +
cast(@Minute as varchar(2)) as datetime)
return @retval
end
go
Para complicar las cosas, me uno a las mesas de zona horaria para comprobar la fecha en contra de la hora local, que puede ser diferente para cada fila:
where
dbo.f_MakeDate(dateadd(hh, tz.Offset +
case when ds.LocalTimeZone is not null
then 1 else 0 end, t.TheDateINeedToCheck), 0, 0) = @activityDateMidnight
[Editar]
I 'm @ incorporar la sugerencia de Todd:
where datediff(day, dateadd(hh, tz.Offset +
case when ds.LocalTimeZone is not null
then 1 else 0 end, t.TheDateINeedToCheck), @ActivityDate) = 0
Mi idea errónea acerca de cómo funciona DateDiff (el mismo día del año en años consecutivos rinde 366, no 0 como esperaba) me hizo perder mucho esfuerzo.
Pero el plan de consulta no cambió. Creo que necesito volver al tablero de dibujo con todo el asunto.
Consulte la respuesta de Mark Brackett, que es la ** correcta **. Me doy cuenta de que su pregunta tiene 2 años, pero por favor no guiemos a la gente por el camino equivocado que visita esta pregunta. La respuesta de Todd Tingen funciona, pero es un rendimiento terrible, como descubriste en ese momento. – ErikE
La respuesta de Mark es correcta para esta situación porque el optimizador depende de ello. Usar dateadd como lo hice es una forma simple y concisa de ver si dos fechas están en el mismo día calendario que fue la pregunta original. – Todd