CodeGym /Corsi /SQL SELF /Influenza di NULL sulle funzioni di aggregazione: SUM(), ...

Influenza di NULL sulle funzioni di aggregazione: SUM(), COUNT(), AVG(), MIN(), MAX()

SQL SELF
Livello 9 , Lezione 2
Disponibile

Ricordiamo che le funzioni di aggregazione sono quelle che lavorano subito con più righe di dati e restituiscono un solo risultato. In PostgreSQL userai spesso queste funzioni di aggregazione:

  • SUM() — somma dei dati.
  • AVG() — calcolo del valore medio.
  • MIN() — ricerca del valore minimo.
  • MAX() — ricerca del valore massimo.
  • COUNT() — conteggio delle righe.

A prima vista sembra tutto facile: passi una colonna o un'espressione alla funzione e ottieni il risultato. Ma cosa succede se nella colonna c'è un NULL?

Comportamento di NULL negli aggregati: panoramica veloce

Qui inizia la parte interessante:

  • SUM() e AVG() ignorano NULL. Se almeno un record ha valore NULL, semplicemente non viene considerato nei calcoli. Un comportamento abbastanza logico: come può crescere la somma se qualcuno "non è venuto alla festa"? O come calcoli la media se manca un valore?
  • MIN() e MAX() saltano anche loro i NULL. Cercano il valore minimo o massimo solo tra i dati che non sono NULL. Quindi, se cerchi lo studente più giovane che ha dimenticato di inserire la data di nascita, NULL non vincerà mai.
  • COUNT(*) conta tutte le righe, anche quelle dove c'è NULL. Invece COUNT(column) conta solo le righe dove nella colonna specificata c'è un valore, cioè NULL viene ignorato.

Dai, vediamolo con degli esempi.

Esempi di uso delle funzioni di aggregazione con NULL

Ecco la tabella students_scores, che contiene i voti degli studenti per un test:

student_id name score
1 Alisa 85
2 Bob NULL
3 Charli 92
4 Dana NULL
5 Elena 74

Ora facciamo qualche query e analizziamo i risultati:

  1. Somma di tutti i voti: SUM()
SELECT SUM(score) AS total_score
FROM students_scores;

Risultato:

total_score
251

Come vedi, i valori NULL mancanti non sono stati sommati. Per Alisa (85), Charli (92) ed Elena (74) la somma è 251. Bob e Dana sono rimasti fuori.

  1. Voto medio: AVG()
SELECT AVG(score) AS average_score
FROM students_scores;

Risultato:

average_score
83.67

Di nuovo, NULL sono stati ignorati e la media è stata calcolata solo per chi ha un voto: (85 + 92 + 74) / 3 = 83.67.

  1. Voto minimo e massimo: MIN() e MAX()
SELECT
    MIN(score) AS min_score, 
    MAX(score) AS max_score 
FROM students_scores;

Risultato:

min_score max_score
74 92

Anche qui tutto semplice: i valori NULL sono stati ignorati, il minimo è 74 e il massimo è 92.

  1. Conteggio delle righe: COUNT(*) vs COUNT(column)
SELECT
    COUNT(*) AS total_rows, 
    COUNT(score) AS non_null_scores 
FROM students_scores;

Risultato:

total_rows non_null_scores
5 3
  • COUNT(*) ha contato tutte le righe, anche quelle dove score è NULL.
  • COUNT(score) ha contato solo le righe dove nella colonna score c'è un valore.

Casi pratici

Vediamo qualche esempio pratico.

Esempio 1: Conteggio dei dipendenti con e senza stipendio indicato

Supponiamo di avere una tabella employees con gli stipendi.

id name salary
1 Alex Lin 50000
2 Maria Chi NULL
3 Anna Song 60000
4 Otto Art NULL
5 Liam Park 55000

Vogliamo sapere quanti dipendenti hanno indicato lo stipendio e quanti no.

SELECT
    COUNT(*) AS total_employees,
    COUNT(salary) AS employees_with_salary,
    COUNT(*) - COUNT(salary) AS employees_without_salary
FROM employees;

Qui:

  • COUNT(*) restituisce il numero totale di dipendenti.
  • COUNT(salary) conta quanti hanno indicato lo stipendio.
  • Per calcolare quanti non hanno lo stipendio, basta sottrarre un valore dall'altro.

Risultato

total_employees employees_with_salary employees_without_salary
5 3 2

Esempio 2: Calcolo del prezzo medio dei prodotti considerando i dati mancanti

Sei il proprietario di un negozio magico e nella tabella products c'è la colonna price, ma per alcuni prodotti il prezzo non è ancora indicato.

id name price
1 Magic Wand 150
2 Enchanted Cloak NULL
3 Potion Bottle 75
4 Spell Book 200
5 Crystal Ball NULL

Devi sapere il prezzo medio solo per i prodotti dove è stato inserito.

SELECT AVG(price) AS average_price
FROM products;

Risultato:

average_price
141.6667

Se vuoi impostare un prezzo di default per i prodotti senza prezzo (ad esempio 0), puoi usare la funzione COALESCE() che vedremo nella prossima lezione.

Esempio 3: Trovare l'età minima e massima degli studenti

Nella tabella students c'è l'età degli studenti, ma per alcuni non è nota (NULL).

id name age
1 Alex Lin 20
2 Maria Chi NULL
3 Anna Song 19
4 Otto Art 22
5 Liam Park NULL

Vogliamo sapere chi è lo studente più giovane e quello più anziano.

SELECT
    MIN(age) AS youngest_student,
    MAX(age) AS eldest_student
FROM students;

Risultato:

youngest_student eldest_student
19 22

Questa query restituisce l'età minima e massima solo per gli studenti che hanno l'età indicata. NULL viene di nuovo saltato.

Particolarità e insidie

Quando lavori con NULL negli aggregati, ricordati questi punti:

  • Nella somma SUM() e nella media AVG() i NULL non vengono considerati. Puoi sfruttarlo per non aggiungere valori "vuoti" nei calcoli.
  • Se vuoi contare anche le righe con NULL in una colonna, usa COUNT(*).
  • Con MIN() o MAX(), NULL non influisce sul risultato. Però, se tutta la colonna è solo NULL, anche il risultato sarà NULL.

Consigli per lavorare con NULL

  1. Considera il contesto del problema. È importante capire se devi considerare i NULL nella tua query. A volte, come con AVG(), ignorarli è proprio quello che serve. Altre volte, come quando conti il totale, è importante includere anche le righe con NULL.
  2. Usa COALESCE() se serve. Se vuoi sostituire NULL con un valore di default nei calcoli, la funzione COALESCE() diventerà la tua amica (ma questa è roba per la prossima lezione).
  3. Non confondere COUNT(*) e COUNT(column). Questo è un errore classico dei principianti. Il primo conta tutte le righe, il secondo solo quelle con valori non nulli.

Ora sai come il silenzioso NULL può influenzare gli aggregati. Questa conoscenza ti aiuterà ad evitare brutte sorprese e a usare NULL a tuo vantaggio. Nella prossima lezione vedremo il potente strumento COALESCE() per gestire i NULL ancora meglio.

Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION