Pergunta

Eu quero limitar um relatório para retornar registros de Data à Data B. Isto é o que eu tenho feito:

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 foi dito registros retornados de 12:00 01 de janeiro através 23:59 31 mar (que a meia-noite é o padrão quando nenhum momento é indicado). Mas eu notei uma discrepância, que é se um registro tem um tempo de 00:00:00 que será parte deste conjunto.

Existe uma maneira mais exata de fazer isso para que ele irá retornar exatamente o intervalo de datas que eu quero? *

Eu tentei usar tempo:

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

... mas eu notei algo instável: SQL Server irá arredondar para cima centésimo de segundo pela metade. Então eu conseguir que 1 de abril de registro (ha! Registro da Mentira! GRR) se eu usar a qualquer hora mais tarde do que 11:59:29. Por que isso?

  • (tenho certeza de que existe. Eu sou novo nisso. Obrigado por sua ajuda!)
Foi útil?

Solução

Há sempre a opção mais 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

Outras dicas

Eu suspeito que a coluna de data em view_Inspections é um tipo de dados smalldatetime. Este tipo de dados tem uma precisão de 1 minuto, o que explica os resultados inesperados (arredondando os segundos para o minuto mais próximo).

O método de Roland Shaw sugere é a melhor maneira de modificar sua consulta para acomodar suas necessidades.

O operador BETWEEN é inclusiva, razão pela qual você está vendo os resultados que você está em sua primeira consulta. O arredondamento que você está vendo em sua segunda consulta vai ser dependente do que exato de data e hora tipo de dados você está usando em sua mesa. (BTW, eu acho que você está confundindo segundos com centésimos de segundos). Parece que você está provavelmente usando um smalldatetime em sua tabela, caso em que o tempo é arredondado para o minuto mais próximo.

Se a tabela está usando data e hora, tente explicitamente converter seu @startDate e @EndDate para DATETIME valores (CAST (@EndDate AS DATETIME)).

Uma nota rápida ... mesmo para valores DATETIME, SQL Server só é preciso para os 3 / 100ths de um segundo, então 11: 59: 59.999 vai ser arredondado para 12: 00:. 00.000

Você tem basicamente três opções:

1) ENTRE CAST ('01 / 01/2008 00: 00: 00.000' AS DATETIME) e elenco ('03 / 31/2008 12: 59: 59,997' AS DATETIME)

2) ANO (my_date) = 2008 E MÊS (my_date) entre 1 e 3

3) my_date> = CAST ('01 / 01/2008 00: 00: 00.000' AS DATETIME) E my_date

O primeiro método não é muito intuitivo e é propenso a erros na minha opinião. O segundo método mata desempenho desde índices não pode ser utilizado e torna-se muito mais complexo se você pode ter pesquisas que anos de calibração ou começar / fim no meio do mês. O terceiro método, que Rowland sugerido, é o melhor que eu penso.

Simplesmente tente remover o tempo a partir do campo de data assim:

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))

Isto irá devolver tudo, desde 01/01/2008 00:00:00 para 04/01/2008 11:59:59.999. Se você não quer 04/01 incluído, alterar a data de término para 03/31/2008.

Sua melhor solução é apenas criar um campo BIGINT (10), que chamou de "Julian", e armazená-lo em AAAAMMDD.

Em seguida, fazer a consulta onde Julian> = '20120103' e Julian <= '20120203'

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top