Lezione 8 — Funzioni aggregate in MySQL: COUNT, SUM e AVG

Scopri come utilizzare le funzioni aggregate di MySQL per analizzare i dati: impara a contare record, sommare valori e calcolare medie in modo efficiente.

Introduzione alle Funzioni Aggregate

Nel mondo dei database relazionali, e in particolare in MySQL, non sempre abbiamo bisogno di recuperare ogni singolo record di una tabella. Spesso, l'obiettivo di una query non è visualizzare i dati grezzi, ma ottenere delle informazioni sintetiche, ovvero dei riepiloghi statistici. Ad esempio, un amministratore di un e-commerce non vuole necessariamente vedere ogni singolo ordine effettuato in un giorno, ma desidera sapere quanti ordini sono stati ricevuti o qual è l'incasso totale della giornata.

Qui entrano in gioco le funzioni aggregate. Una funzione si dice "aggregata" quando opera su un insieme di valori (una colonna di più righe) per restituire un unico valore riassuntivo. Queste funzioni sono fondamentali per la creazione di report, dashboard e analisi di business.

In questa lezione approfondiremo le tre funzioni aggregate più utilizzate: COUNT(), SUM() e AVG(), analizzandone il funzionamento, i casi d'uso e le differenze cruciali.

La funzione COUNT(): Contare i record

La funzione COUNT() è probabilmente la più utilizzata tra le funzioni aggregate. Il suo scopo è semplice: contare il numero di righe che soddisfano determinati criteri.

Differenza tra COUNT(*) e COUNT(colonna)

Molti principianti confondono l'uso di COUNT(*) con COUNT(nome_colonna). Sebbene sembrino identici, c'è una differenza tecnica fondamentale legata ai valori NULL.

  1. COUNT(*): Conta tutte le righe della tabella, indipendentemente dal contenuto. Anche se una riga contiene valori NULL in tutte le colonne, verrà comunque contata.
  2. COUNT(colonna): Conta solo le righe in cui il valore della colonna specificata non è NULL. Se una riga ha un valore NULL nella colonna indicata, quella riga viene esclusa dal conteggio.

Esempio Pratico di COUNT

Immaginiamo di avere una tabella chiamata utenti con le colonne id, nome, email e telefono. Alcuni utenti potrebbero non aver fornito il numero di telefono.

-- Contiamo quanti utenti totali sono registrati nel database
SELECT COUNT(*) AS totale_utenti 
FROM utenti;

-- Contiamo quanti utenti hanno effettivamente inserito un numero di telefono
SELECT COUNT(telefono) AS utenti_con_telefono 
FROM utenti;

In questo esempio, se abbiamo 100 utenti ma solo 80 hanno inserito il telefono, la prima query restituirà 100, mentre la seconda restituirà 80. L'uso dell'alias AS è fortemente consigliato per dare un nome leggibile alla colonna risultante, altrimenti MySQL utilizzerà il nome della funzione stessa come intestazione.

La funzione SUM(): Sommare i valori

La funzione SUM() viene utilizzata per calcolare la somma totale dei valori di una colonna numerica. A differenza di COUNT(), che conta le occorrenze, SUM() somma i valori contenuti nelle celle.

Caratteristiche di SUM()

  • Funziona solo su colonne di tipo numerico (INTEGER, DECIMAL, FLOAT, ecc.).
  • Ignora i valori NULL: se una riga contiene NULL, viene semplicemente saltata senza influenzare il risultato (non viene considerata come zero, ma proprio ignorata).
  • Se non ci sono righe che soddisfano i criteri o se tutti i valori sono NULL, SUM() restituirà NULL.

Esempio Pratico di SUM

Consideriamo una tabella ordini che contiene una colonna importo per ogni acquisto effettuato.

-- Calcoliamo l'incasso totale di tutti gli ordini effettuati
SELECT SUM(importo) AS incasso_totale 
FROM ordini;

-- Calcoliamo l'incasso totale solo per gli ordini che hanno superato i 50 euro
SELECT SUM(importo) AS incasso_ordini_alti 
FROM ordini 
WHERE importo > 50;

In questo caso, la clausola WHERE filtra prima le righe e poi SUM() somma solo i valori rimasti. Questo è un pattern comune: filtrare i dati per poi aggregarli.

La funzione AVG(): Calcolare la media

La funzione AVG() (abbreviazione di Average) calcola la media aritmetica dei valori di una colonna numerica. Matematicamente, AVG() è l'equivalente di fare SUM(colonna) / COUNT(colonna).

Comportamento di AVG()

Proprio come SUM(), anche AVG() ignora i valori NULL. Questo è un punto critico: se hai 10 prodotti, di cui 5 hanno un prezzo di 10€ e 5 hanno un prezzo NULL, AVG() calcolerà la media solo sui 5 prodotti che hanno un prezzo, restituendo 10€. Non dividerà per 10, ma per 5.

Esempio Pratico di AVG

Utilizziamo la stessa tabella ordini per capire qual è il valore medio di un ordine nel nostro negozio.

-- Calcoliamo il valore medio di tutti gli ordini
SELECT AVG(importo) AS valore_medio_ordine 
FROM ordini;

-- Calcoliamo la media degli ordini per un cliente specifico (id_cliente = 12)
SELECT AVG(importo) AS media_cliente_12 
FROM ordini 
WHERE id_cliente = 12;

Spesso il risultato di AVG() contiene molte cifre decimali. Per rendere il risultato più leggibile, è comune combinare AVG() con la funzione ROUND() per arrotondare il valore.

-- Media arrotondata a due cifre decimali
SELECT ROUND(AVG(importo), 2) AS media_arrotondata 
FROM ordini;

Casi d'uso reali e combinazioni

Nella pratica professionale, raramente si usa una sola funzione aggregata in modo isolato. Spesso vengono combinate per ottenere un quadro completo della situazione.

Scenario: Analisi di un Magazzino

Immaginiamo una tabella prodotti con le colonne nome, prezzo e quantita.

SELECT 
    COUNT(*) AS numero_prodotti, 
    SUM(quantita) AS pezzi_totali_magazzino, 
    AVG(prezzo) AS prezzo_medio_catalogo, 
    MIN(prezzo) AS prezzo_minimo, 
    MAX(prezzo) AS prezzo_massimo
FROM prodotti;

In un'unica query, abbiamo ottenuto cinque informazioni vitali sul nostro inventario. Nota l'aggiunta di MIN() e MAX(), altre due funzioni aggregate che restituiscono rispettivamente il valore più basso e quello più alto di una colonna.

Errori comuni e FAQ

Perché ricevo l'errore "Invalid use of group function"?

Uno degli errori più comuni per i beginner è tentare di usare una funzione aggregata all'interno della clausola WHERE.

Esempio Errato: SELECT * FROM ordini WHERE SUM(importo) > 1000;

Perché è sbagliato? La clausola WHERE filtra le singole righe prima che l'aggregazione avvenga. Non puoi filtrare le righe basandoti su un risultato che deve ancora essere calcolato.

Soluzione: Per filtrare i risultati di una funzione aggregata, devi usare la clausola HAVING (che studieremo nelle lezioni successive insieme a GROUP BY).

Cosa succede se la tabella è vuota?

  • COUNT(*) restituirà 0.
  • SUM() e AVG() restituiranno NULL.

È importante gestire questi valori NULL nel codice dell'applicazione (PHP, JavaScript, ecc.) per evitare errori di calcolo nel frontend.

Prossimi passi

Abbiamo visto come riassumere l'intera tabella in un unico valore. Ma cosa succede se vogliamo i totali per ogni categoria? Ad esempio, l'incasso totale per ogni categoria di prodotti o il numero di ordini per ogni singolo cliente?

Per fare questo, non basta COUNT() o SUM(), ma serve uno strumento chiamato GROUP BY.

In sintesi, ecco cosa ricordare di questa lezione:

  • COUNT(*) conta tutto, COUNT(colonna) conta solo i non-NULL.
  • SUM() somma i valori numerici.
  • AVG() calcola la media, ignorando i NULL.
  • Le funzioni aggregate trasformano molte righe in un unico valore.
  • Non usare mai funzioni aggregate nel WHERE.

Nella prossima lezione, scopriremo come combinare queste funzioni con l'istruzione GROUP BY per creare report professionali e dettagliati.