Funzione LAST_DAY() per FineMese

Gli argomenti di questa pagina

  • Calcolo di fine mese con la funzione LAST_DAY()
  • FineMese con funzioni DATE_ADD e DATE_SUB
  • Esempio con una data arbitraria
  • Esempio su una tabella reale del DB

Calcolo di fine mese con la funzione LAST_DAY()

La funzione MySQL LAST_DAY() restituisce l'ultimo giorno del mese corrispondente per una data o un valore datetime. Se il valore di data o datetime non è valida, la funzione restituisce NULL.
La sintassi è semplice:

LAST_DAY(date1)

La funzione LAST_DAY() restituisce la data completa della fine del mese nel formato AAAA-MM-GG. Perciò, se vogliamo la data formattata in modo diverso o se vogliamo solo il giorno è necessario avvalersi di altre funzioni come nell'esempio.

Cerca l'ultimo del mese delle date di nascita con la funzione LAST_DAY()

esempio 1
1
2
3
4
5
6
7
8
<?php
$Query 
"SELECT id, cognome, nome, data_nascita, 
LAST_DAY( data_nascita) AS ultimo_in_data , 
DATE_FORMAT( LAST_DAY( data_nascita), '%d-%m-%Y') AS ultimo_formattato, 
DAY( LAST_DAY( data_nascita)) AS ultimo_giorno
FROM sql_rubrica  
"
;
?>
101 record trovati
15 record visualizzati
id cognome nome data_nascita ultimo_in_data ultimo_formattato ultimo_giorno
1 Migliavacca Luigi 2004-01-22 2004-01-31 31-01-2004 31
2 Rizzi Carlo 2007-11-22 2007-11-30 30-11-2007 30
3 Liberali Franca 2004-02-20 2004-02-29 29-02-2004 29
4 Di Maggio Mario 2009-05-21 2009-05-31 31-05-2009 31
5 Scicchitano Andrea 1997-01-12 1997-01-31 31-01-1997 31
6 Edelvisi Maurizio 1987-07-02 1987-07-31 31-07-1987 31
7 Gerardini Silvano 2009-08-12 2009-08-31 31-08-2009 31
8 Pasotti Alessio 1987-11-14 1987-11-30 30-11-1987 30
9 Calvi Giovanni 1987-07-26 1987-07-31 31-07-1987 31
10 Poggi Giuseppe 1987-01-25 1987-01-31 31-01-1987 31
11 Curti Oreste 1988-06-26 1988-06-30 30-06-1988 30
12 Borsotti Mirella 1987-07-19 1987-07-31 31-07-1987 31
13 Franchinotti Anna 2009-05-10 2009-05-31 31-05-2009 31
14 Pischedda Giovanni 1999-08-08 1999-08-31 31-08-1999 31
15 Maini Marilena 2002-03-20 2002-03-31 31-03-2002 31
... ... ... ... ... ... ...

FineMese con funzioni DATE_ADD e DATE_SUB

Se vogliamo avventurarci nella programmazione avanzata possiamo fare uso delle funzioni DATE_ADD e DATE_SUB.
Da quel che ho visto girando in giro, MYSQL, nonostante la schiera di funzioni che ha per la gestione dei mesi, non sembra avere una funzione per calcolare la fine del mese.
Per questo motivo ho cercato di vedere se, usando le sue funzioni native, potessi arrivare ad ottenere questo risultato.

Il ragionamento che ho seguito per raggiumgere lo scopo è questo e rispettando la sequenza:

  • trovo il primo del mese della data in esame con la funzione DATE_FORMAT('2014-02-15', '%Y-%m-%01')
    se nella stringa di formattazione usata con la funzione DATE_FORMAT() inserisco una stringa letterale che non è compresa tra i valori predefiniti, questa stringa rimane invariata, quindi se al posto di %d metto una qualsiasi altra stringa (%01) questa rimane ed entra nella stringa restituita dalla funzione.
  • aggiumgo un mese alla data trovata con DATE_ADD( '2014-01-31', INTERVAL 1 MONTH )
  • tolgo un giorno per spostarmi alla fine del mese precedente con DATE_SUB( '2014-02-01', INTERVAL 1 DAY )

se riuscissi a nidificare tutte queste funzioni in una istruzione SELECT (o anche in una WHERE) raggiungo l'obiettivo che mi son posto.
E' quel che cerco di fare in questo esempio ed il risultato che si vede è ottenuto eseguendo l'ultima Query.
Nella istruzione illustrata qui sotto sembra che la sequenza appena descritta sia invertita. Invece, quando le funzioni sono nidificate (qui sotto le funzioni nidificate sono tre, ma nella Query finale sono ben quattro) la loro esecuzione avviene da quella più interna andando via via verso quella più esterna.

DATE_SUB( DATE_ADD( DATE_FORMAT(...) , ... ) , ... )

che così è formulato:
DATE_SUB( DATE_ADD( DATE_FORMAT( '2014-03-15', '%Y-%m-%01' ) , INTERVAL 1 MONTH ) , INTERVAL 1 DAY )

Le altre righe le ho lasciate solo a scopo chiarificativo.
Per molteplici funzioni nidificate la prima ad essere eseguita è la più interna e via via si sale all più esterna.
Quindi, nel nostro esempio le funzioni vengono eseguite in questa sequenza:

  • DATE_FORMAT('2014-02-15', '%Y-%m-%01')
  • DATE_ADD( risultato della funzione DATE_SUB , INTERVAL 1 MONTH )
  • DATE_SUB( risultato della funzione DATE_FORMAT, INTERVAL 1 DAY )

Esempio con una data arbitraria

Stabilita una data arbitraria, trovare: l'inizio del mese, il mese successivo, il giorno precedente e l'ultimo del mese

esempio 2
1
2
3
4
5
6
7
8
9
<?php
$Query 
" SELECT '2014-02-15' AS data_esame, 
DATE_FORMAT('2014-02-15', '%Y-%m-%01') AS inizio_mese,
DATE_ADD( '2014-02-15', INTERVAL 1 MONTH ) AS mese_prossimo, 
DATE_SUB( '2014-02-15', INTERVAL 1 DAY ) AS giorno_precedente, 
DATE_SUB( DATE_ADD( DATE_FORMAT( '2014-02-15', '%Y-%m-%01' ) , INTERVAL 1 MONTH ) , INTERVAL 1 DAY ) 
AS FineM 
"
;
?>
1 record letti
data_esame inizio_mese mese_prossimo giorno_precedente FineM
2014-02-15 2014-02-01 2014-03-15 2014-02-14 2014-02-28

Esempio su una tabella reale del DB

Ora vediamo lo stesso calcolo in azione su una vera tabella MYSQL. In questo caso ho allungato l'output del resultset per eseguire un esame più completo su ciò che restituisce l'istruzione.

In questa Query:

  • Nella prima riga, subito dopo la clausola SELECT, chiamo le colonne id, cognome e nome.
  • Nella seconda riga chiamo la colonna data_nascita formattata in maniera adeguata per conoscere la data su cui andremo a lavorare.
  • La terza riga è fondamentalmente quella che dovrebbe restituire l'ultimo giorno del mese ed in genere vediamo che lo restituisce. Tuttavia vediamo che restiutisce alcune incoerenze in corrispondenza di alcuni mesi.
  • Nella quarta riga della Query ho cercato di modificare l'istruzione della terza riga invertendo la funzione DATE_ADD() con la funzione DATE_SUB() mantenendo per ciascuna gli argomenti "INTERVAL 1 DAY" associato a "DATE_SUB" e "INTERVAL 1 MONTH" associato a "DATE_ADD".
    Perciò sembra che questa sia la giusta sequenza per ottenere la giusta fine del mese.
DATE_SUB( DATE_ADD( DATE_FORMAT( data_nascita, '%Y-%m-%01' ) , INTERVAL 1 MONTH ) , INTERVAL 1 DAY )

Ed ora la Query finale

Cerca la fine del mese delle date di nascita con la funzione DATE_ADD()

esempio 3
1
2
3
4
5
6
7
8
<?php
$Query 
"SELECT id, cognome, nome, 
DATE_FORMAT( data_nascita, '%d-%m-%Y' ) AS Nato_Il , 
DATE_FORMAT( DATE_ADD( DATE_SUB( DATE_FORMAT( data_nascita, '%Y-%m-%01'), INTERVAL 1 DAY), INTERVAL 1 MONTH), '%d-%m-%Y') AS FineM_no_buona, 
DATE_FORMAT( DATE_SUB( DATE_ADD( DATE_FORMAT( data_nascita, '%Y-%m-%01'), INTERVAL 1 MONTH), INTERVAL 1 DAY), '%d-%m-%Y') AS FineM 
FROM sql_rubrica 
"
;
?>
101 record trovati
15 record visualizzati
id cognome nome Nato_Il FineM_no_buona FineM
1 Migliavacca Luigi 22-01-2004 31-01-2004 31-01-2004
2 Rizzi Carlo 22-11-2007 30-11-2007 30-11-2007
3 Liberali Franca 20-02-2004 29-02-2004 29-02-2004
4 Di Maggio Mario 21-05-2009 30-05-2009 31-05-2009
5 Scicchitano Andrea 12-01-1997 31-01-1997 31-01-1997
6 Edelvisi Maurizio 02-07-1987 30-07-1987 31-07-1987
7 Gerardini Silvano 12-08-2009 31-08-2009 31-08-2009
8 Pasotti Alessio 14-11-1987 30-11-1987 30-11-1987
9 Calvi Giovanni 26-07-1987 30-07-1987 31-07-1987
10 Poggi Giuseppe 25-01-1987 31-01-1987 31-01-1987
11 Curti Oreste 26-06-1988 30-06-1988 30-06-1988
12 Borsotti Mirella 19-07-1987 30-07-1987 31-07-1987
13 Franchinotti Anna 10-05-2009 30-05-2009 31-05-2009
14 Pischedda Giovanni 08-08-1999 31-08-1999 31-08-1999
15 Maini Marilena 20-03-2002 28-03-2002 31-03-2002
... ... ... ... ... ...

 

 



settore tecnico il sito di lorettabweb il Forum di sostegno
il forum il forum il forum