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 a un prodotto, un cliente, un evento, eccetera)
- una data
- un attributo descrittivo del codice che cambia a 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