Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Converti i campi datetime del server SQL per confrontare solo le parti della data, con ricerche indicizzate

Il modo migliore per eliminare la parte temporale di un campo datetime è utilizzare le funzioni datediff e dateadd.

   DateAdd(day, datediff(day,0, MydateValue), 0)

Ciò sfrutta il fatto che SQL Server archivia le date come due numeri interi, uno che rappresenta il numero di giorni dal giorno "0" - (1 gennaio 1900) e il secondo che rappresenta il numero di tick (ogni tick è di circa 3,33 ms) dalla mezzanotte (per l'ora) *.

la formula sopra deve semplicemente leggere solo il primo intero. Non è richiesta alcuna conversione o elaborazione, quindi è estremamente veloce.

Per fare in modo che le tue query utilizzino un indice... usa questa formula prima sui parametri di filtraggio di input o sull'"altro" lato del segno di uguale dal campo data e ora delle tabelle, in modo che Query Optimizer non debba eseguire il calcolo su ogni campo datetime della tabella per determinare quali righe soddisfano il predicato del filtro. Questo rende il tuo argomento di ricerca "SARG-able" (Search ARGument)

Where MyDateTimeColumn > DateAdd(day, 
      datediff(day,0, @MydateParameter), 0)    -- SARG-able

piuttosto che

Where DateAdd(day, datediff(day,0, 
      MyDateTimeColumn ), 0) > @MydateParameter -- Not SARG-able

* NOTA. Internamente, il secondo intero (la parte temporale) memorizza i tick. In un giorno ci sono 24 x 60 X 60 X 300 =25.920.000 tick (fortuitamente appena al di sotto del valore massimo che può contenere un intero a 32 bit). Tuttavia, non devi preoccuparti di questo quando modifichi aritmeticamente un datetime... Quando aggiungi o sottrai valori da datetimes puoi trattare il valore come una frazione come se fosse esattamente uguale alla parte frazionaria di un giorno, come se il il valore completo datetime era un numero in virgola mobile costituito da una parte intera che rappresenta la data e la parte frazionaria che rappresenta l'ora). cioè,

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