Como remover as horas da data (datetime) no SQL Server

Olá PessoALL,

Hoje post pratico e rápido… e o título meio estranho ao ler… mas como removemos a hora, minuto e segundo de um campo de datatype DATETIME no SQL Server? Ou truncar as horas, como é dito por muitos profissionais Oracle?. Sabe aqueles momentos que você quer buscar todos os registros de um único dia mas ele possui hora, minuto e segundo?

Pois bem….. vamos a principio lembrar que existem N tipos de datatypes para se trabalhar com datas no SQL Server. Eles estão listados aqui neste link. Vamos lembrar também que o SQL Server não salva datas com formato, como já postei e exemplifiquei neste post.

Agora… a título de ilustração vamos imaginar a tabela abaixo.

create table table2
(
id_registro int primary key identity,
horario_registro datetime not null,
comentario varchar(512) not null
);

Imagine que nesta tabela possui diversos registros por dia (horario_registro) e você quer apenas os de hoje. Quais são as opções?

Talvez essa?

select * from table2
where horario_registro = '20160622'

A consulta acima não irá trazer nenhum registro, por que? Claro…. você está passando o dia que será realizado “casting” dele para o DATETIME, que terá as “horas zeradas”, ou seja meia-noite, e nenhum registro foi inserido nesse horário. Como eu sei que foi “castado” para datetime? Veja o plano de execução.

predicate_datetime

Pois bem…. então vamos remover as horas do “horario_registro” ou melhor dizendo realizar “casting” dele para DATE.


select * from table2
where cast(horario_registro as date) = '20160622'

Agora sim ….. temos o resultado que queríamos… certo?

A solução vai funcionar muito bem para pequenas tabelas e validações rápidas.

Como ela funciona? O campo “horario_registro” será convertido para o tipo DATE, este não armazena hora, minuto e segundo. Assim o SQL Server não usará esses atributos durante o comparativo. O SQL Server é inteligente e fará também o casting do valor a ser pesquisado para DATE, diferente da ultima tentativa que foi feito casting para DATETIME.
Vejamos no plano de execução….
predicate_date

Pois bem… então o “zerar as horas” ou “truncar as horas” é simplesmente o casting do campo/valor de DATETIME para DATE? Exatamente!

Agora… esse método é o recomendado? Não! Por que não? Porque ele irá atrapalhar o SQL Server de usar índices! Então como podemos procurar um dia inteiro em um campo de DATETIME?


-- Usando menor ( < )
select * from table2
where horario_registro >= '20160622 00:00:00'
and horario_registro < '20160623 00:00:00'

ou…

-- Usando menor igual ( <= )
select * from table2
where horario_registro >= '20160622 00:00:00'
and horario_registro <= '20160622 23:59:59.997'
<pre>

Ou usando variáveis…

declare @hoje_inicio datetime = cast(getdate() as date)
declare @hoje_final datetime = dateadd(day, 1, @hoje_inicio)

-- Usando menor ( < )
select * from table2
where horario_registro >= @hoje_inicio
and horario_registro < @hoje_final

ou…

declare @hoje_inicio datetime = cast(getdate() as date)
declare @hoje_final datetime = dateadd(day, 1, @hoje_inicio)

-- Usando menor igual ( <= )
set @hoje_final = dateadd(MILLISECOND, -3, dateadd(day, 1, @hoje_inicio) )
select * from table2
where horario_registro >= @hoje_inicio
and horario_registro <= @hoje_final

Explicando…

Por que a variável é DATETIME e foi atribuido o getdate() com CAST as DATE? Para truncar as horas! A variável terá o valor do dia de hoje com as como “00:00:00.000”!

Por que “20160622 23:59:59.997” e “dateadd(MILLISECOND, -3”? Porque o tipo DATETIME possui a precisão de até três casas após segundos, ou em milissegundos. Isso muda conforme muda o tipo para smalldatetime, timestamp, datetime2 e etc.

Em resumo…. pratico e rápido? Principalmente usando em variáveis?  CAST as DATE!

Por hoje é só… vou corrigindo e aprimorando com o tempo…. vlw!

Publicidade
Esse post foi publicado em SQLServer e marcado , , , , , , , , , , , , . Guardar link permanente.

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s