SQL Server: filtro su campi datetime

In questo articolo vedremo come scrivere correttamente una query sul database SQL Server che effettui un filtro su un campo datetime. Occorre prestare molta attenzione perché senza le giuste conoscenze potremmo incappare in risultati errati.

 

Sintassi di base per filtrare una colonna datetime

Per prima cosa vediamo con quale formato scrivere il valore con cui vogliamo filtrare la colonna datetime. Il consiglio che mi sento di dare vivamente è quello di utilizzare esclusivamente il formato ISO 8601  che è indipendente da ogni settaggio relativo alla lingua dell’utente che fa login nel database.

Il formato ISO 8601 è YYYY-MM-DDThh:mi:ss.mmm, occorre cioè riportare in ordine

  • anno, mese e giorno intervallati dal carattere trattino “-“
  • il carattere T
  • ore minuti e secondi intervallati dal carattere due punti “:”
  • il carattere punto “.” seguito da tre decimali (opzionale)

Potremmo scrivere ad esempio

SELECT *

FROM    MovimentiCarta

WHERE DataMovimento <= ‘2020-01-01T12:25:23.000’

È fondamentale sottolineare che i decimali dei secondo sono arrotondati a .000, .003 o .007 secondi. Nel prossimo paragrafo vedremo come la mancata conoscenza di questa informazione può provocare dei gravi errori.

 

Arrotondamento dei decimali di colonne datetime

Guardiamo del codice d’esempio che ci aiuterà a comprendere le tipologie di errori che possiamo commettere se non consideriamo le regole di arrotondamento dei decimali di una colonna datetime.

Per prima cosa creiamo una tabella temporanea con una colonna di tipo datetime, costruita convertendo esplicitamente in datetime una data. Tale conversione avrà l’effetto di aggiungere l’orario 00:00:00.000.

SELECT Convert(Datetime,’20190101′) as CampoDateTime

INTO #test;

Vediamo ora cosa succede se filtriamo le due query utilizzando due sintassi leggermente diverse.

SELECT Count(*) FROM #test WHERE CampoDateTime <= ‘2018-12-31T23:59:59.999’

SELECT Count(*) FROM #test WHERE CampoDateTime < ‘2019-01-01’

Queste query restituiscono (probabilmente inaspettatamente) risultati differenti.

Infatti, se confrontato con un datetime, il valore ‘20181231 23:59:59.999‘ viene approssimato alla mezzanotte del 1 gennaio 2019 e di conseguenza risulta uguale al valore presente nella colonna. Nell’ultima query invece, stiamo considerando correttamente le righe con valori strettamente minore del 1 gennaio 2019.

Comprendere tale logica può risultare molto importante quando dobbiamo scrivere query per estrarre informazioni come “tutte le fatture del 2018” e vogliamo evitare l’utilizzo di funzioni come Month e Year per ragioni di performance (esse infatti potrebbero impedire l’utilizzo di indici). A tal fine, per evitare qualsiasi problema legato al tipo dei dati, il mio consiglio è quello di utilizzare sempre un doppio filtro con un maggiore uguale a sinistra e un minore stretto a destra. Ad esempio scriveremmo

SELECT * FROM Fatture WHERE DataFattura >= ‘2018-01-01’ and DataFattura < ‘2019-01-01’

e questo risulterà corretto per ogni tipologia di dato.

 

Altre peculiarità di datetime e confronto con datetime2

È importante sapere che una colonna datetime non accetta valori precedenti il 1 Gennaio 1753. Inoltre ogni valore memorizzato in una colonna datetime consuma ben 8 bytes.

Le colonne di tipo datetime2 non hanno invece limiti inferiori di salvataggio, la prima data disponibile è il 1 gennaio dell’anno 1. Inoltre di default accettano fino a 7 cifre decimali di secondi evitando il problema di approssimazione presentato nel paragrafo precedente del datetime. Inoltre specificando in fase di creazione datetime2(2) avremo solo 2 cifre per i decimi di secondo, ma per ogni valore occuperemo solamente 6 bytes (ben 2 bytes in meno rispetto a valori datetime).

Gli aspetti qui descritti fanno riferimento a un database SQL Server. In ambiente Oracle tale situazione merita ulteriori approfondimenti in quanto già le colonne di tipo date memorizzano informazioni sull’ora, i minuti e i secondi.

 

Corsi correlati

Se cerchi un corso per fare un upgrade del tuo SQL e diventare un vero esperto leggi la scheda del nostro corso su SQL Server e il linguaggio T-SQL.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.

Torna su