Vai al contenuto
eLearner.app
Modulo 4 · Lezione 2 di 414/57 nel corso~10 min
Lezioni del modulo (2/4)

Gestire i NULL: IS NULL e COALESCE

Nel dataset employees, Andrea Costa è speciale: ha department_id = NULL. Hai già incontrato NULL di sfuggita (col LEFT JOIN), ma è arrivato il momento di prenderlo sul serio: i NULL in SQL si comportano in modo diverso da qualsiasi altro valore, e ignorarli è una delle prime cause di bug nel codice di produzione.

NULL non è zero, non è stringa vuota

NULL significa valore sconosciuto / assente. Non è 0, non è '', non è false. È "non lo so". Da questo discende una proprietà sorprendente: NULL non è uguale a niente, nemmeno a se stesso.

SQL
-- Tutte queste espressioni restituiscono NULL (e non true!):
SELECT NULL = NULL;       -- NULL
SELECT NULL = 0;          -- NULL
SELECT NULL <> 'qualcosa'; -- NULL

Conseguenza concreta: WHERE colonna = NULL non funziona mai. Devi usare gli operatori dedicati IS NULL / IS NOT NULL:

SQL
-- Dipendenti senza dipartimento:
SELECT first_name, last_name
FROM   employees
WHERE  department_id IS NULL;

-- Dipendenti CON un dipartimento:
SELECT first_name, last_name
FROM   employees
WHERE  department_id IS NOT NULL;

COALESCE — il fallback per NULL

Spesso vuoi mostrare qualcosa al posto di NULL quando il dato manca: la stringa '(nessuno)', lo zero, una data di default. La funzione che fa esattamente questo si chiama COALESCE(a, b, c, ...): restituisce il primo argomento non-NULL della lista.

SQL
-- Mostra il department_id, o 0 se manca:
SELECT first_name, last_name, COALESCE(department_id, 0) AS dept
FROM   employees;

Con un LEFT JOIN diventa potentissima per i report:

SQL
SELECT e.first_name,
       e.last_name,
       COALESCE(d.name, '(nessun dipartimento)') AS dipartimento
FROM   employees   AS e
LEFT JOIN departments AS d ON e.department_id = d.id;

Risultato: tutti i dipendenti restituiti, con il nome del dipartimento o l'etichetta esplicita per chi non ne ha uno.

NULL e gli aggregati

Le funzioni di aggregazione ignorano i NULL (eccetto COUNT(*)):

  • COUNT(department_id) conta solo le righe con un valore;
  • AVG(salary) calcola la media ignorando i NULL, non li tratta come 0;
  • SUM(...) somma solo i non-NULL.

Questo è quasi sempre quello che vuoi. Ma è bene saperlo: se cerchi "il numero totale di dipendenti" usa COUNT(*), non COUNT(department_id).

Prova tu

Esercizio#sql.m4.l2.e1
Tentativi: 0Caricamento…

Per tutti i dipendenti, mostra nome (first_name), cognome (last_name) e una colonna 'dipartimento_id' che vale il loro department_id oppure -1 se non è assegnato. Tre colonne, una riga per dipendente.

Caricamento editor…
Mostra suggerimento

Usa COALESCE(department_id, -1) per sostituire i NULL con -1.

Soluzione disponibile dopo 3 tentativi

Esercizio di ripasso

Esercizio#sql.m4.l2.e2
Tentativi: 0Caricamento…

Restituisci nome (first_name), cognome (last_name) e nome del dipartimento (departments.name) di TUTTI i dipendenti, mostrando '(nessuno)' quando il dipartimento manca. Usa LEFT JOIN + COALESCE.

Caricamento editor…
Mostra suggerimento

COALESCE(d.name, '(nessuno)') gestisce il NULL introdotto dal LEFT JOIN.

Soluzione disponibile dopo 3 tentativi