DateTime – Problema del Fine mese… e non solo
Se il vostro responsabile vi chiedesse di tirare fuori tutti gli ordini che l’azienda ha emesso tutti i fine mese di ogni anno fino ad oggi, come vi comportereste?
Devo ammettere che fino a qualche giorno fa ho utilizzato una tabella di appoggio di date, dalla quale per ogni mese tiravo fuori il massimo giorno. Oggi (meglio tardi che mai!) ho scoperto un trucchetto niente male!
Utilizziamo il “famigerato” database AdventureWork, in particolare la tabella Sales.SalesOrderHeader. Scrivendo la semplice query seguente, si ottiene quanto richiesto:
La data ‘19991231’ è una data di riferimento che può essere una qualunque data avente anno ‘aaaa’ e mese ‘mm’ a piacere, tali che la data ‘aaaamm31’ sia valida.
La funzione DATEDIFF(month, ‘aaamm31’, O.orderdate) restituisce il numero di mesi che intercorrono tra la data di riferimento e la data dell’ordine (può anche essere un numero negativo). Se poi si somma tale numero di mesi alla data di riferimento (quasi una operazione inversa), si ottiene una data che ha come anno e mese gli stessi della data dell’ordine, ma come giorno lo stesso della data di riferimento se questo, insieme ad anno e mese, forma una data valida; altrimenti viene preso il più grande giorno del mese in modo tale da formare una data valida.
Se si utilizzasse come data di riferimento la data ‘19991229’, si filtrerebbero tutti gli ordini emessi il giorno 29 di ogni mese (eccezion fatta per febbraio se non è bisestile nell’anno di emissione dell’ordine).
Dunque, se la data di riferimento è ‘19991231’, oppure ad esempio ‘29990831’, si ottengono gli ordini emessi l’ultimo giorno di ogni mese. Se invece prendiamo come data di riferimento, ad esempio, la data ‘20000101’, otteniamo gli ordini emessi il primo di ogni mese (il giorno 1 insieme a qualunque mese e anno forma sempre una data valida).
Alla luce di ciò, teniamo presente che possiamo usare, come data di riferimento, anche la data 0:
e quindi possiamo facilmente ottenere, ad esempio, le date di oggi e di ieri con l’azzeramento dell’ora, come segue:
Allo stesso modo possiamo ottenere alcune date (sempre con l’ora azzerata) “comode” per eventuali confronti:
E’ anche possibile lavorare con cifre decimali per gestire le “porzioni” dei giorni (in questo caso la “mezza giornata”):
Lo stesso risultato si sarebbe potuto ottenere usando, ad esempio, la data di riferimento '20010401 12:00:00'.
A questo punto non posso che augurare un buon DateTime a tutti voi! :)