Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Converter campos de data e hora do SQL Server para comparar apenas partes de data, com pesquisas indexadas


A melhor maneira de remover a parte de hora de um campo de data e hora é usar as funções datediff e dateadd.
   DateAdd(day, datediff(day,0, MydateValue), 0)

Isso tira proveito do fato de que o SQL Server armazena datas como dois inteiros, um representando o número de dias desde o dia "0" - (1 jan 1900), e o segundo que representa o número de tiques (cada tick é de cerca de 3,33 ms) desde a meia-noite (para o horário) *.

a fórmula acima simplesmente tem que ler apenas o primeiro inteiro. Não há necessidade de conversão ou processamento, por isso é extremamente rápido.

Para fazer suas consultas usar um índice... use esta fórmula nos parâmetros de filtragem de entrada primeiro, ou no "outro" lado do sinal de igual do campo de data e hora da tabela, para que o otimizador de consulta não precise executar o cálculo em cada campo de data e hora na tabela para determinar quais linhas satisfazem o predicado do filtro. Isso torna seu argumento de pesquisa "capaz de SARG" (Search ARGument)
Where MyDateTimeColumn > DateAdd(day, 
      datediff(day,0, @MydateParameter), 0)    -- SARG-able

ao invés de
Where DateAdd(day, datediff(day,0, 
      MyDateTimeColumn ), 0) > @MydateParameter -- Not SARG-able

* NOTA. Internamente, o segundo inteiro (a parte do tempo) armazena ticks. Em um dia há 24 x 60 X 60 X 300 =25.920.000 ticks (por acaso logo abaixo do valor máximo que um inteiro de 32 bits pode conter). No entanto, você não precisa se preocupar com isso ao modificar aritmeticamente um datetime... Ao adicionar ou subtrair valores de datetimes você pode tratar o valor como uma fração como se fosse exatamente igual à parte fracionária de um dia, como se o valor O valor de data e hora completo era um número de ponto flutuante que consistia em uma parte inteira representando a data e a parte fracionária representando a hora). ou seja,
`Declare @Dt DateTime  Set @Dt = getdate()  
 Set @Dt = @Dt + 1.0/24  -- Adds one hour  
 Select @Dt  
 Set @Dt = @Dt - .25 -- Moves back 6 hours  
 Select @Dt`