Compare a parte do tempo de DATETIME e DATE ignorando


151

Eu tenho duas tabelas onde coluna [date]é o tipo de DATETIME2(0).

Eu tenho que comparar dois registros apenas pelas partes Date (dia + mês + ano), descartando partes Time (horas + minutos + segundos).

Como eu posso fazer isso?

Respostas:


252

Use o CASTpara o novo DATEtipo de dados no SQL Server 2008 para comparar apenas a parte da data:

IF CAST(DateField1 AS DATE) = CAST(DateField2 AS DATE)

61

Uma pequena desvantagem na resposta de Marc é que os dois campos de datas foram impressos, o que significa que você não poderá alavancar nenhum índice.

Portanto, se houver necessidade de escrever uma consulta que possa se beneficiar de um índice em um campo de data, a seguinte abordagem (bastante complicada) será necessária.

  • O campo de data indexado (denominado DF1) deve ser intocado por qualquer tipo de função.
  • Portanto, você deve comparar o DF1 com o intervalo completo de valores de data e hora para o dia do DF2.
  • Isso é da parte da data do DF2 até a parte da data do dia após o DF2.
  • Ou seja, (DF1 >= CAST(DF2 AS DATE)) AND (DF1 < DATEADD(dd, 1, CAST(DF2 AS DATE)))
  • NOTA : É muito importante que a comparação seja > = (igualdade permitida) com a data do DF2 e (estritamente) < no dia seguinte ao DF2. Além disso, o operador BETWEEN não funciona porque permite igualdade nos dois lados.

PS: Outro meio de extrair apenas a data (em versões mais antigas do SQL Server) é usar um truque de como a data é representada internamente.

  • Lance a data como uma bóia.
  • Truncar a parte fracionária
  • Lance o valor de volta para um datetime
  • Ou seja, CAST(FLOOR(CAST(DF2 AS FLOAT)) AS DATETIME)

5

Embora tenha votado positivamente na resposta marcada como correta. Eu queria tocar em algumas coisas para quem se deparar com isso.

Em geral, se você estiver filtrando especificamente apenas os valores de Data . A Microsoft recomenda usar o formato neutro de idioma de ymdou y-m-d.

Observe que o formulário '2007-02-12' é considerado neutro em idioma apenas para os tipos de dados DATE, DATETIME2 e DATETIMEOFFSET.

Fazer uma comparação de datas usando a abordagem mencionada acima é simples. Considere o seguinte exemplo 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

Em um mundo perfeito, a execução de qualquer manipulação na coluna filtrada deve ser evitada, pois isso pode impedir o SQL Server de usar índices com eficiência. Dito isto, se os dados que você está armazenando estão preocupados apenas com a data e não com a hora, considere armazenar DATETIMEcom a meia-noite como a hora. Porque:

Quando o SQL Server converte o literal no tipo da coluna filtrada, ele assume a meia-noite quando uma parte do tempo não é indicada. Se você deseja que esse filtro retorne todas as linhas a partir da data especificada, certifique-se de armazenar todos os valores com a meia-noite como a hora.

Assim, supondo que você esteja preocupado apenas com a data e armazene seus dados como tal. A consulta acima pode ser simplificada para:

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

select 
    * 
from 
    Sales.Orders
where
    OrderDate = @filterDate

3

Você pode tentar este

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

Eu testo isso para o MS SQL 2014 seguindo o código

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

-3

Para Compare duas datas como MM / DD / AAAA a MM / DD / AAAA . Lembre-se de que o primeiro tipo de coluna do campo deve ser dateTime. Exemplo: columnName: payment_date dataType: datetime .

Depois disso, você pode facilmente compará-lo. A consulta é:

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

É muito simples ...... Ele testou .....


Isso não responde bem à pergunta. Ele consulta por um mês, não um dia.
Curtis Yallop

Para sua consulta de março: se a data for '31/03/2015', 13:00, ela não será encontrada. Você deve usar <'4/1/2015'.
Curtis Yallop

Considere também usar o formato de data internacional '2015-03-01'. No Canadá (e em muitos outros lugares), um formato oficial é DD / MM / AAAA, o que torna os dois formatos ambíguos e problemáticos.
Curtis Yallop 21/07

Esta resposta não lida com 2 tabelas, conforme solicitado na pergunta.
Curtis Yallop

Sim im concordar, mas im apenas provando solução não solução internacional .. você tem que mudar alguma ordem ...
pankaj
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.