27th Jul 2023 Tempo di lettura: 10 minuti Panoramica delle funzioni finestra di MySQL Dominika Florczykowska sql MySQL window functions Indice Cosa sono le Window Functions in MySQL? Come definire una funzione finestra: La clausola OVER() Esempi di query con funzioni finestra in MySQL Esempio 1: Clausola OVER() vuota - Calcolo di una statistica per tutte le righe Esempio 2: OVER() con ORDER BY - Calcolo di una classifica Esempio 3: OVER() con PARTITION BY - Calcolo di una statistica per ogni partizione Esempio 4: OVER() con PARTITION BY e ORDER BY - Calcolo di una statistica per ogni partizione in un ordine specifico Pronti a fare pratica con MySQL Window Functions? Le funzioni finestra di MySQL sono molto utili quando si desidera creare rapporti significativi con SQL. In questo articolo illustreremo le funzioni finestra più comuni in MySQL e spiegheremo come utilizzarle. MySQL 8.0 ha introdotto una nuova caratteristica: le funzioni finestra. Queste funzioni sono molto utili per gli analisti di dati e per tutti coloro che creano report con MySQL. Grazie ad esse è possibile calcolare facilmente medie mobili, somme cumulative e altri calcoli su sottoinsiemi specifici di dati. Il tutto senza creare complesse query SQL o tabelle temporanee. Chi utilizza abitualmente SQL potrebbe essersi imbattuto nelle funzioni finestra nel proprio lavoro. Mentre molti database dispongono di queste funzioni da tempo, MySQL è rimasto indietro fino al 2018. Con MySQL 8, la piattaforma è ora al passo con i tempi! In questo articolo esploreremo i vantaggi delle funzioni finestra in MySQL e come possono migliorare l'analisi dei dati. Se volete fare pratica con le funzioni a finestra, date un'occhiata al nostro corso interattivo Window Functions in MySQL 8. Offre oltre 200 esercizi interattivi sulle funzioni finestra di MySQL. Cosa sono le Window Functions in MySQL? Una funzione finestra SQL esegue calcoli su un insieme di righe della tabella che sono correlate alla riga corrente. Questo insieme di righe è chiamato finestra o cornice di finestra, da cui deriva il termine "funzioni finestra". Cominciamo con un semplice esempio. Immaginiamo di voler calcolare la somma dei valori di tutte le righe, ma di voler visualizzare il risultato su ogni riga. Questa informazione potrebbe servire per confrontare i singoli valori con il totale durante l'analisi dei dati. Questo è un gioco da ragazzi se si sanno usare le funzioni delle finestre! Il risultato della vostra query sarà simile a questo: monthrevenuetotal January10,00080,000 February20,00080,000 March20,00080,000 April30,00080,000 Avrete notato che le funzioni finestra sono simili alle funzioni aggregate. Entrambe calcolano un valore aggregato per un certo gruppo di righe. Tuttavia, a differenza della clausola GROUP BY, le funzioni finestra in SQL non comprimono le righe. Al contrario, la tabella risultante mostra sia i valori individuali che quelli aggregati. Questo può essere utile nei report in cui è necessario lavorare con i valori aggregati e non aggregati allo stesso tempo. Come definire una funzione finestra: La clausola OVER() Le funzioni finestra si definiscono con la clausola OVER(): SELECT …, <window_function> OVER(...), … FROM … La clausola OVER() indica al database di utilizzare una funzione finestra. La forma più semplice della finestra è quando le parentesi sono lasciate vuote, come in questo caso: OVER(). Ciò significa che la finestra è costituita da tutte le righe della tabella. È possibile includere altre clausole all'interno della clausola OVER() per definire ulteriormente la finestra. In questo articolo, ci concentreremo sulle clausole PARTITION BY e ORDER BY. Esistono altre clausole che possono essere utilizzate all'interno di OVER(), ma non saranno trattate in questo articolo. Se volete approfondire l'argomento, date un'occhiata al nostro corso Window Functions in MySQL 8. In alternativa, potete visitare questo articolo sulle funzioni finestra di MySQL , che fornisce alcuni ottimi esempi di come utilizzarle nelle vostre query. Esempi di query con funzioni finestra in MySQL Esaminiamo alcuni esempi di query per capire meglio dove e come è possibile utilizzare le funzioni finestra. Nel nostro scenario di esempio, abbiamo un sito web che permette agli utenti di partecipare a dei quiz. Ci sono varie categorie di quiz e il numero massimo di punti che i partecipanti possono ottenere è 100. Per memorizzare i punteggi dei partecipanti, si utilizza una query di questo tipo. Per memorizzare i punteggi dei partecipanti, questo sito web utilizza la tabella participant tabella. Essa ha le seguenti colonne: id - L'ID del partecipante, che è anche la chiave primaria (PK) della tabella. name - Il nome del partecipante. quiz_score - Il punteggio del partecipante. quiz_date - La data in cui è stato tentato il quiz. quiz_category - La categoria del quiz. Qui si può vedere una manciata di righe della tabella: idnamequiz_scorequiz_datequiz_category 1Charlee Freeman902023-04-10science 2Christina Rivas252023-04-02history 3Amira Palmer1002023-04-01history 4Carlos Lopez782023-04-04music 5Alba Gomez452023-04-05music 6Michael Doe922023-04-12science 7Anna Smith862023-04-11science Ora che conoscete i dati, passate all'uso delle funzioni della finestra! Questo foglio di istruzioni di SQL Window Functions può essere utile come guida di riferimento rapida durante la lettura degli esempi. Esempio 1: Clausola OVER() vuota - Calcolo di una statistica per tutte le righe Supponiamo di voler restituire il punteggio di ogni partecipante, la categoria del quiz che ha tentato e il punteggio più alto mai raggiunto in tutti i quiz. Possiamo farlo utilizzando una clausola vuota OVER(). In questo modo, la finestra includerà tutte le righe della query. Ecco la query da eseguire: SELECT name, quiz_score, quiz_category, MAX(quiz_score) OVER() AS max_score FROM participant; Il risultato sarà il seguente: namequiz_scorequiz_categorymax_score Charlee Freeman90science100 Christina Rivas25history100 Amira Palmer100history100 Carlos Lopez78music100 Alba Gomez45music100 Michael Doe92science100 Anna Smith86science100 La funzione MAX() è stata applicata a tutte le righe della query. Si può notare che il punteggio più alto è 100 e viene visualizzato per tutte le righe insieme ai singoli punteggi. È possibile utilizzare la clausola vuota OVER() con altre funzioni, come COUNT(), SUM(), AVG() e altre. Ciò consente di calcolare una statistica complessiva per tutte le righe della query; è possibile confrontare questa statistica complessiva con il valore di ogni singola riga. Per ulteriori informazioni sull'uso della clausola OVER() in MySQL, consultare l'articolo Cos'è la clausola OVER di MySQL? Esempio 2: OVER() con ORDER BY - Calcolo di una classifica Quando viene utilizzata all'interno della clausola OVER(), ORDER BY determina l'ordine delle righe nel riquadro della finestra. Vediamo un esempio: Possiamo utilizzare questa query per creare una classifica dei punteggi dei quiz: SELECT name, quiz_score, quiz_category, RANK() OVER(ORDER BY quiz_score DESC) AS rank FROM participant; La funzione finestra RANK() assegna un rango a ogni riga all'interno di una partizione; questo rango si basa sul valore di un'espressione specificata. La prima riga ottiene il rango 1, la seconda il rango 2, ecc. Più precisamente, la funzione RANK() assegna un rango unico a ogni valore distinto dell'espressione all'interno della partizione. Le righe con lo stesso valore avranno lo stesso rango e il rango successivo verrà saltato. Ad esempio, se due righe hanno lo stesso valore e ricevono un rango pari a 1, il rango successivo assegnato sarà 3, saltando il rango 2. Per ulteriori informazioni sulle funzioni di ranking window in SQL, consultare il nostro blog. In questo caso, utilizziamo la funzione RANK() per calcolare la classifica del punteggio di ogni partecipante al quiz. La clausola OVER() con la clausola ORDER BY determina l'ordine di applicazione della funzione RANK(). In questo caso, la clausola ORDER BY è impostata su quiz_score DESC, il che significa che i punteggi dei quiz sono ordinati in ordine decrescente (dal più alto al più basso) prima di calcolare la classifica. La prima riga (con il valore più alto) ottiene il rango 1, la seconda riga il rango 2 e così via. Ecco cosa restituisce il codice: namequiz_scorequiz_categoryrank Amira Palmer100history1 Michael Doe92science2 Charlee Freeman90science3 Anna Smith86science4 Carlos Lopez78music5 Alba Gomez45music6 Christina Rivas25history7 Ben fatto! Siamo riusciti ad assegnare a ciascun partecipante un rango. Utilizzate la clausola OVER (ORDER BY) in MySQL quando volete applicare una funzione alle righe in un ordine specifico. Questo può essere utile per calcolare totali, medie mobili e creare varie classifiche. Esempio 3: OVER() con PARTITION BY - Calcolo di una statistica per ogni partizione Facciamo un ulteriore uso della colonna categoria. Ricordate il primo esempio di query? Per ogni partecipante, abbiamo visualizzato il suo punteggio, la categoria del quiz che ha tentato e il punteggio più alto mai ottenuto in tutti i quiz. Questa volta vogliamo fare qualcosa di simile. Tuttavia, invece di mostrare il punteggio più alto mai ottenuto in tutti i quiz, mostreremo il punteggio più alto mai ottenuto nella categoria di quel quiz. Per questo, avremo bisogno della clausola OVER() con PARTITION BY. Partire i dati in SQL significa dividere un insieme di righe in gruppi più piccoli in base a una o più colonne specificate. È un po' simile alla clausola GROUP BY, ma le funzioni finestra non comprimono le righe. Possiamo usare questa query: SELECT name, quiz_score, quiz_category, MAX(quiz_score) OVER(PARTITION BY quiz_category) AS max_score_in_category FROM participant; La clausola PARTITION BY con la clausola OVER() determina la partizione dei dati su cui viene applicata la funzione MAX(). In questo caso, la clausola PARTITION BY è impostata su quiz_category, il che significa che i dati sono divisi in partizioni basate sulla categoria del quiz. È esattamente quello che volevamo! Ecco il risultato: namequiz_scorequiz_categorymax_score_in_category Amira Palmer100history100 Christina Rivas25history100 Carlos Lopez78music78 Alba Gomez45music78 Anna Smith86science92 Michael Doe92science92 Charlee Freeman90science92 Per ogni partecipante, abbiamo visualizzato sia il suo punteggio individuale sia il punteggio più alto della sua categoria. Sembra giusto, visto che il quiz di musica poteva essere più difficile di quello di scienze! OVER (PARTITION BY) in MySQL è utile per calcolare somme cumulative o valori medi, creare classifiche all'interno di gruppi, identificare i migliori o i peggiori risultati e molto altro ancora. Questa clausola fornisce flessibilità e funzionalità avanzate alle query SQL, consentendo una potente analisi e manipolazione dei dati all'interno di sottoinsiemi di dati. Per ulteriori informazioni sull'uso di SQL PARTITION BY con OVER, consultare il nostro blog. È stato facile, vero? Proviamo qualcosa di più complicato! Esempio 4: OVER() con PARTITION BY e ORDER BY - Calcolo di una statistica per ogni partizione in un ordine specifico Possiamo usare contemporaneamente PARTITION BY e ORDER BY? Certamente! Questa combinazione è utile in molte situazioni. In MySQL, l'uso della clausola OVER() con PARTITION BY e ORDER BY consente di eseguire calcoli e analisi su partizioni specifiche di dati, controllando l'ordine in cui i calcoli vengono applicati all'interno di ciascuna partizione. La clausola PARTITION BY divide l'insieme dei risultati in partizioni distinte basate su colonne o espressioni specificate. Ogni partizione viene trattata separatamente per il calcolo o l'analisi. La clausola ORDER BY, se usata con OVER(), determina l'ordine di elaborazione dei dati all'interno di ogni partizione. Specifica la colonna o l'espressione in base alla quale i dati devono essere ordinati. Vediamo questa coppia in azione. In questo esempio, calcoleremo la media cumulativa dei punteggi dei quiz per categoria. Una media cumulativa è la media di un insieme di valori fino a un certo punto. Questa è la query che utilizzeremo: SELECT name, quiz_date, quiz_score, quiz_category, ROUND( AVG(quiz_score) OVER(PARTITION BY quiz_category ORDER BY quiz_date) ) AS cumulative_avg FROM participant; Vorremmo vedere la media cumulativa dei punteggi dei quiz per categoria. Per ottenere questo risultato, abbiamo utilizzato PARTITION BY quiz_category, proprio come abbiamo fatto l'ultima volta. Inoltre, è logico che la media cumulativa sia calcolata dalla data più vecchia a quella più recente, quindi abbiamo usato ORDER BY quiz_date. Ciò significa che i dati all'interno di ogni partizione vengono ordinati in base alla data del quiz in ordine crescente (dal più grande al più piccolo) prima che venga applicata la funzione AVG(). Ecco come appare l'output della query: namequiz_datequiz_scorequiz_categorycumulative_avg Amira Palmer2023-04-01100history100 Christina Rivas2023-04-0225history63 Carlos Lopez2023-04-0478music78 Alba Gomez2023-04-0545music62 Charlee Freeman2023-04-1090science90 Anna Smith2023-04-1186science88 Michael Doe2023-04-1292science89 Utilizzando PARTITION BY e ORDER BY insieme alla clausola OVER(), il calcolo della media viene applicato separatamente per ogni categoria di quiz. All'interno di ogni categoria, la media viene calcolata nell'ordine delle date dei quiz. Ciò significa che per ogni riga del set di risultati, il calcolo della media considera solo le righe della stessa categoria di quiz e le ordina per data. La colonna cumulative_avg rifletterà il punteggio medio fino alla riga corrente per ogni categoria di quiz, tenendo conto dell'ordine delle date dei quiz. Pronti a fare pratica con MySQL Window Functions? Come potete vedere, le funzioni finestra di MySQL sono uno strumento molto potente che può aiutarvi a creare rapporti complessi. È possibile utilizzare le funzioni finestra in MySQL per creare classifiche e calcolare metriche anno su anno, medie mobili e molto altro ancora! In questo articolo abbiamo solo scalfito la superficie di tutti i modi in cui è possibile utilizzare le funzioni finestra. Se volete approfondire ed esplorare altri esempi di utilizzo, date un'occhiata a questi articoli sulle funzioni finestra di SQL e sulla clausola OVER() di MySQL. E per una maggiore pratica, ricordatevi di dare un'occhiata al nostro corso Window Functions in MySQL 8! Tags: sql MySQL window functions