In questa lezione parliamo di un classico problema da affrontare con il linguaggio SQL di non semplicissima soluzione: trovare il record più recente per ogni raggruppamento. Spieghiamo meglio il problema riportandone la struttura e dei casi d’esempio. Solitamente sono coinvolte tre colonne principali:
- un codice identificativo (ad esempio relativo ad un prodotto, un cliente, un evento, eccetera)
- una data
- un attributo descrittivo del codice che cambia ad ogni data (ad esempio il prezzo per il prodotto, la regione di residenza per il cliente, eccetera)
Vogliamo estrarre per ogni codice il valore dell’attributo alla data più recente. Ad esempio a partire da questi dati
IdProdotto | Data | Prezzo |
1 | 01/01/2020 | 20 |
1 | 03/05/2020 | 19 |
1 | 07/05/2020 | 18 |
2 | 04/03/2020 | 15 |
2 | 03/06/2020 | 13 |
2 | 11/11/2020 | 14 |
vogliamo estrarre le sole due righe
IdProdotto | Data | Prezzo |
1 | 07/05/2020 | 18 |
2 | 11/11/2020 | 14 |
perché relative ai prezzi più recenti per ogni prodotto.
Ricorda: non copiare e incollare il codice senza aver effettuato tutti i test necessari per ogni caso specifico.
Risoluzione in SQL
Per risolvere questo problema possiamo utilizzare una Window Function (qui trovi un mio articolo dedicato). Scriveremo
WITH CTE AS ( SELECT IdProdotto, Data, Prezzo, RANK() OVER( PARTITION BY IdProdotto ORDER BY Data DESC) AS Rn FROM Tabella ) SELECT IdProdotto, Data, Prezzo FROM CTE WHERE Rn = 1;
Nel caso ci fossero più righe con la stessa DataFattura più recente, il codice precedente restituirebbe tutti i record associati. Se vogliamo un unico risultato possiamo:
- inserire ulteriori criteri di ordinamento all’interno dell’ORDER BY della funzione RANK in modo da disambiguare tutti i pari merito;
- utilizzare una funzione non deterministica, il cui output potrebbe variare da esecuzione a esecuzione. Più precisamente possiamo sostituire RANK() con ROWNUMBER() e saremo sicuri di avere sempre una sola riga.
La seconda soluzione è ovviamente meno consigliata rispetto alla prima e attuabile solo in precise circostanze da valutare con attenzione.
Altri esercizi
- Esercizi sulle Window Function e temi avanzati
- Scrivere SQL dinamico per l’operatore PIVOT
- Esercitiamoci con Pandas e Python