Pregunta

Quiero limitar un informe para que devuelva registros desde la Fecha A hasta la Fecha B. Esto es lo que he estado haciendo:

declare @startDate varchar(20)
declare @endDate varchar(20)
set @startDate = '01/01/2008'
set @endDate = '04/01/2008'
-- test what are the start and end dates
select min(date),max(date) from view_Inspections 
where date between @startDate and @endDate

... que me dijeron que devolvió los registros desde las 12 am del 1 de enero hasta las 11:59 pm del 31 de marzo (esa medianoche es el valor predeterminado cuando no se indica la hora). Pero noté una discrepancia, que es si un registro tiene un tiempo de 00:00:00 que formará parte de este conjunto.

¿Hay una manera más exacta de hacer esto para que devuelva exactamente el rango de fechas que quiero? *

Intenté usar el tiempo:

declare @startDate varchar(20)
declare @endDate varchar(20)
set @startDate = '01/01/2008 00:00:00'
set @endDate = '04/01/2008 11:59:59'
-- test what are the start and end dates
select min(date),max(date) from view_Inspections 
where date between @startDate and @endDate

... pero noté algo inestable: SQL Server REDONDARÁ el centésimo segundo por la mitad. Así que obtengo ese registro del 1 de abril (¡ja! ¡Registro de los inocentes! Grr) si lo uso en cualquier momento después de las 11:59:29. ¿Por qué es eso?

  • (Estoy seguro de que sí. Soy nuevo en esto. ¡Gracias por tu ayuda!)
¿Fue útil?

Solución

Siempre existe la opción fácil:

declare @startDate varchar(20)
declare @endDate varchar(20)
set @startDate = '01/01/2008'
set @endDate = '04/01/2008'

-- test what are the start and end dates
select min(date),max(date) from view_Inspections 
where date >= @startDate 
and   date < @endDate

Otros consejos

Sospecho que la columna de fecha en view_Inspections es un tipo de datos SmallDateTime. Este tipo de datos tiene una precisión de 1 minuto, lo que explica sus resultados inesperados (redondeando los segundos al minuto más cercano).

El método que sugiere Roland Shaw es la mejor manera de modificar su consulta para satisfacer sus necesidades.

El operador ENTRE es inclusivo, por lo que está viendo los resultados que está en su primera consulta. El redondeo que está viendo en su segunda consulta dependerá del tipo de datos de fecha y hora exactos que esté utilizando en su tabla. (Por cierto, creo que estás confundiendo segundos con centésimas de segundo). Parece que probablemente estés usando una fecha pequeña en tu tabla, en cuyo caso la hora se redondea al minuto más cercano.

Si su tabla usa datetime, intente convertir explícitamente sus valores @startDate y @endDate a DATETIME (CAST (@endDate AS DATETIME)).

Una nota rápida ... incluso para los valores DATETIME, SQL Server solo tiene una precisión de 3/100 de segundo, por lo que 11: 59: 59.999 se redondeará a 12: 00: 00.000.

Básicamente tienes tres opciones:

1) ENTRE CAST ('01 / 01/2008 00: 00: 00.000 'COMO FECHA DE FECHA) Y CAST ('03 / 31/2008 12: 59: 59.997' COMO FECHA DE FECHA)

2) AÑO (my_date) = 2008 Y MES (my_date) ENTRE 1 Y 3

3) my_date > = CAST ('01 / 01/2008 00: 00: 00,000 'AS DATETIME) Y my_date < CAST ('04 / 01/2008 00: 00: 00,000 'COMO FECHA DE HORA)

El primer método no es muy intuitivo y, en mi opinión, es propenso a errores. El segundo método mata el rendimiento ya que los índices no se pueden usar y se vuelve mucho más complejo si puede realizar búsquedas que abarquen años o que comiencen / terminen a mediados de los meses. El tercer método, que sugirió Rowland, es el mejor, creo.

Simplemente intente eliminar la hora del campo de fecha de esta manera:

declare @startDate varchar(20)
declare @endDate varchar(20)
set @startDate = '01/01/2008'
set @endDate = '04/01/2008'

SELECT min(date),max(date) FROM view_Inspections 
WHERE CAST(FLOOR(CAST(date AS FLOAT)) AS DATETIME) BETWEEN CAST(@startDate AS DATETIME) And CAST(@startDate AS DATETIME))

Esto devolverá todo, desde 01/01/2008 00:00:00 a 04/01/2008 11:59:59.999. Si no desea que se incluya 04/01, cambie su fecha de finalización a 03/31/2008.

Su mejor solución es crear un campo BIGINT (10) que se llame " julian " ;, y almacenarlo en AAAAMMDD.

Luego haz la consulta donde julian > = '20120103' Y julian < = '20120203'

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top