È arrivato il momento di andare a fondo sugli errori tipici che capitano quando usi queste funzioni. Anche i più esperti di SQL ogni tanto ci cascano, e il nostro obiettivo è imparare a riconoscere queste trappole e a evitarle con stile.
Hai mai scritto una query e ti sei beccato un errore strano tipo "column must appear in the GROUP BY clause or be used in an aggregate function"? O magari il risultato della tua query era strano e non avevi idea del perché? Questo è solo la punta dell’iceberg degli errori tipici con le funzioni di aggregazione. Questa lezione è la tua guida di sopravvivenza nel mare degli errori e dei malintesi.
Errore 1: Uso di una colonna non aggregata fuori dal GROUP BY
Problema
Hai scritto una query che restituisce dati aggregati, ma ci hai infilato dentro una colonna che non fa parte del raggruppamento e non è dentro una funzione di aggregazione. Tipo così:
SELECT department, salary, SUM(salary)
FROM employees
GROUP BY department;
PostgreSQL ti risponde subito:
ERROR: column "employees.salary" must appear in the GROUP BY clause or be used in an aggregate function
Perché succede?
Quando usi GROUP BY, PostgreSQL raggruppa le righe in base alle colonne che hai indicato. Ma se aggiungi un’altra colonna (in questo caso salary), PostgreSQL non sa cosa farci. Non capisce se vuoi solo uno stipendio, la media o qualcos’altro.
Come risolvere? Hai due strade:
- Assicurati che tutte le colonne non aggregate siano nel
GROUP BY:
SELECT department, salary
FROM employees
GROUP BY department, salary;
- Oppure metti la colonna dentro una funzione di aggregazione, se ha senso:
SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department;
Consiglio: se PostgreSQL si lamenta del GROUP BY, chiediti: "Questa colonna mi serve davvero nella query? Se sì, che ruolo ha esattamente?"
Errore 2: Uso sbagliato di COUNT() e NULL
Problema: vuoi contare quanti dipendenti hanno indicato il loro bonus, e scrivi:
SELECT COUNT(bonus) AS bonus_count
FROM employees;
Ma poi noti che il risultato è più basso di quanto ti aspettavi. Perché? Perché COUNT(column) ignora le righe dove column è NULL.
Soluzione: se vuoi contare proprio tutte le righe, usa COUNT(*):
SELECT COUNT(*) AS total_count
FROM employees;
Oppure specifica che ti interessano solo le righe dove il bonus non è NULL:
SELECT COUNT(bonus) AS bonus_count
FROM employees
WHERE bonus IS NOT NULL;
Dritta: se vuoi distinguere tra i record che hanno NULL e l’assenza totale di record nella tabella, scegli con attenzione tra COUNT(*) e COUNT(column).
Errore 3: Dimenticare di filtrare con HAVING invece di WHERE
Problema: vuoi trovare i reparti dove lo stipendio medio supera 5000. Un dev alle prime armi potrebbe scrivere qualcosa tipo:
SELECT department, AVG(salary) AS avg_salary
FROM employees
WHERE AVG(salary) > 5000
GROUP BY department;
PostgreSQL ti butta fuori un errore:
ERROR: aggregate functions are not allowed in WHERE clause
Succede perché il filtro con WHERE viene eseguito prima del raggruppamento, mentre le funzioni di aggregazione vengono calcolate dopo il raggruppamento. Quindi la media AVG(salary) non è ancora calcolata quando parte il WHERE.
Per risolvere, usa HAVING per filtrare i dati aggregati:
SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department
HAVING AVG(salary) > 5000;
Errore 4: Filtro con WHERE e confusione sull’ordine di esecuzione
Problema: vuoi sapere quanti dipendenti ci sono nei reparti dove l’età è maggiore di 30 anni. La query potrebbe essere così:
SELECT department, COUNT(*)
FROM employees
GROUP BY department
WHERE age > 30;
PostgreSQL ti delude di nuovo:
ERROR: syntax error at or near "WHERE"
Perché succede? L’operatore WHERE viene sempre processato prima del GROUP BY. In questo caso hai solo messo WHERE nel posto sbagliato.
Per evitare questo scenario, cambia l’ordine: prima filtra le righe, poi raggruppa.
SELECT department, COUNT(*)
FROM employees
WHERE age > 30
GROUP BY department;
Errore 5: Uso di NULL con SUM(), AVG() e altre funzioni
Problema: vuoi trovare il bonus totale dato ai dipendenti, e scrivi:
SELECT SUM(bonus) AS total_bonus
FROM employees;
Ma il risultato ti sembra stranamente basso. Tutto perché metà dei dipendenti non ha il bonus indicato, e quei NULL vengono semplicemente ignorati.
Soluzione: gestisci i NULL in anticipo. Ad esempio, puoi sostituire i NULL con 0:
SELECT SUM(COALESCE(bonus, 0)) AS total_bonus
FROM employees;
Ora tutti i NULL saranno sostituiti da 0, e la somma sarà corretta.
Vedremo nel dettaglio come funziona COALESCE tra un paio di lezioni.
Errore 6: Uso di più funzioni di aggregazione senza capirne la relazione
Problema: vuoi contare il numero totale di dipendenti e la somma totale degli stipendi. Ma scrivi qualcosa che dà risultati strani:
SELECT COUNT(salary) AS count_salary, SUM(salary) AS total_salary
FROM employees;
Perché qui può andare tutto storto? Se qualcuno ha lo stipendio NULL, COUNT(salary) e SUM(salary) daranno risultati diversi, e può confondere.
Ricorda sempre che le funzioni di aggregazione lavorano in modo indipendente. Se ci sono NULL, otterrai risultati diversi. Usa COALESCE o COUNT(*) per avere coerenza:
SELECT COUNT(*) AS total_employees, SUM(COALESCE(salary, 0)) AS total_salary
FROM employees;
Errore 7: Query non ottimizzate con troppi raggruppamenti
Problema: lanci una query con un sacco di raggruppamenti e ci mette cinque ore invece di cinque minuti:
SELECT department, job_title, location, COUNT(*)
FROM employees
GROUP BY department, job_title, location;
Prima di fare il raggruppamento, chiediti se ti servono davvero tutte le colonne nel GROUP BY. Più valori unici hai nel gruppo, più la query sarà lenta. Se puoi, riduci il raggruppamento:
SELECT department, COUNT(*)
FROM employees
GROUP BY department;
Questi errori sono comuni, e anche i dev SQL più esperti ci inciampano. Spero che ora ti sarà più facile evitare questi scogli e scrivere query che vanno veloci, sono corrette e pure belle da vedere.
GO TO FULL VERSION