Menu

SQLite e NULL: IS NULL, COALESCE e IFNULL

Come si comportano gli operatori di SQLite con NULL: perché = e <> non funzionano come ti aspetti, e quando usare IS NULL, IS NOT NULL, COALESCE e IFNULL.

Questa pagina include editor eseguibili: modifica, esegui e vedi subito l'output.

NULL significa "sconosciuto"

Ogni altro valore in SQLite rappresenta qualcosa di preciso: un numero, una stringa, un blob. NULL è diverso. È un segnaposto per un valore mancante o sconosciuto. Questa sola idea spiega tutte le stranezze che NULL combina nelle query.

Crea una piccola tabella per fare qualche prova:

Due colonne ammettono valori nulli. Boris non ha un'email. Cleo non ha un'età. Dan non ha nessuna delle due. Il resto della pagina spiega come interrogare righe come queste senza cadere in trappola.

= e <> non funzionano con NULL

Il primo istinto è scrivere WHERE email = NULL. Sembra ragionevole. E non restituisce niente:

Zero righe, anche se Boris e Dan hanno chiaramente l'email nulla. Il motivo: confrontare qualsiasi cosa con NULL produce NULL, non vero o falso. La clausola WHERE di SQLite tiene solo le righe in cui la condizione è vera, e NULL non è vero. Quindi la riga viene scartata.

La stessa trappola con <>:

Ti aspetteresti di ottenere tutti tranne Ada. Invece ottieni solo Cleo. Boris e Dan, che hanno l'email nulla, spariscono, perché anche NULL <> 'ada@example.com' è NULL, non vero.

È in assoluto l'errore più comune in SQL. Ogni volta che una query "perde righe" senza motivo apparente, sospetta di una colonna con valori nulli.

Usa IS NULL e IS NOT NULL

Il modo corretto per verificare se un valore è nullo è l'operatore IS. A differenza di =, conosce i nulli e restituisce vero o falso, mai nullo:

La prima query restituisce Boris e Dan. La seconda restituisce Ada e Cleo. IS NULL e IS NOT NULL sono i due operatori pensati apposta per chiedere "manca questo valore?". Usali ogni volta che ti viene la tentazione di scrivere = NULL o <> NULL.

Se vuoi "tutti tranne Ada, compresi quelli sconosciuti", combina i controlli in modo esplicito:

Ora compaiono Boris, Cleo e Dan.

NULL si propaga in aritmetica e concatenazione

La regola dello "sconosciuto" non vale solo per i confronti. Qualsiasi operazione che tocca un null produce un null:

next_year e doubled sono nulli per Cleo e Dan. Anche labelled_age è nullo per loro: concatenare una stringa con NULL dà NULL, non 'Età: '. Se una colonna può essere nulla e ti serve un valore utilizzabile alla fine, devi gestirla tu. Qui entrano in gioco le prossime due funzioni.

IFNULL: un valore di riserva con due argomenti

IFNULL(a, b) restituisce a, a meno che non sia nullo: in quel caso restituisce b. È il modo più semplice per sostituire un null con un valore predefinito:

Boris e Dan ottengono (nessuna email). Cleo e Dan ottengono 0. I dati originali non cambiano: IFNULL riscrive solo l'output.

IFNULL accetta sempre esattamente due argomenti. Se ti servono più alternative, usa COALESCE.

COALESCE: vince il primo non NULL

COALESCE(a, b, c, ...) scorre i suoi argomenti da sinistra a destra e restituisce il primo che non è nullo. Generalizza IFNULL a qualsiasi numero di alternative:

Per Ada e Cleo viene usata l'email. Per Boris e Dan l'email è nulla, quindi SQLite prova il secondo argomento: un indirizzo costruito a partire dal nome. Se anche quello fosse nullo, passerebbe a 'anonimo'.

COALESCE è la scelta portabile: tutti i principali database SQL la supportano allo stesso modo. IFNULL è una comodità di SQLite e MySQL per il caso con due argomenti. Scegli COALESCE come impostazione predefinita; usa IFNULL solo quando hai davvero due argomenti e preferisci il nome più corto.

NULL non è una stringa vuota

Una confusione frequente: trattare NULL e '' come se fossero intercambiabili. Non lo sono.

'' è una stringa vera che ha semplicemente zero caratteri. NULL è l'assenza di un valore. length('') vale 0; length(NULL) è a sua volta NULL. E NULL = NULL è NULL, non 1: è proprio per questo che esiste IS NULL.

Se una colonna può contenere sia '' sia NULL, decidi quale dei due significa "mancante" e mantieni la scelta. Mescolarli ti costringe a gestire due casi in ogni query, e prima o poi uno lo dimenticherai.

NULL in IN, NOT IN e DISTINCT

Ci sono altri punti in cui il null ti coglie di sorpresa.

IN con una lista che contiene null può dare risultati inattesi, soprattutto con NOT IN:

Potresti aspettarti tutti quelli con un'età diversa da 25. Non ottieni niente. SQLite espande NOT IN (25, NULL) più o meno in age <> 25 AND age <> NULL, e age <> NULL è sempre NULL, quindi l'intera condizione non è mai vera. La soluzione è togliere i null dalla lista (o dalla colonna) prima del confronto.

DISTINCT, invece, considera i null uguali tra loro quando elimina i duplicati:

Ottieni tre righe: l'email di Ada, l'email di Cleo e un solo NULL (che riunisce Boris e Dan). Lo stesso vale per GROUP BY e UNION: trattano i null come un unico gruppo, l'esatto opposto di come li tratta =. SQL non è sempre coerente su questo punto; conviene sapere da che parte sta ogni operatore.

Una checklist veloce

  • Verifica i valori mancanti con IS NULL / IS NOT NULL. Mai con = NULL.
  • Qualsiasi operazione aritmetica, concatenazione o confronto che tocca NULL restituisce NULL.
  • Usa COALESCE(a, b, c, ...) per sostituire i null con un valore di riserva. Usa IFNULL(a, b) come scorciatoia con due argomenti.
  • La stringa vuota '' non è la stessa cosa di NULL. Per ogni colonna scegline una per indicare "mancante".
  • NOT IN (..., NULL) è quasi sempre un bug. Togli prima i null dalla lista.

Prossimo passo: ordinare i risultati

Una volta che sai filtrare correttamente le righe, comprese quelle nulle, il passo successivo è metterle in un ordine utile. ORDER BY è la prossima pagina, e ha le sue regole su dove finiscono i null in un risultato ordinato.

Domande frequenti

Perché colonna = NULL non funziona in SQLite?

Perché NULL significa "sconosciuto", e qualsiasi confronto con un valore sconosciuto è a sua volta sconosciuto, non vero. Quindi WHERE col = NULL non trova nessuna riga, nemmeno quelle in cui la colonna è davvero nulla. Usa invece WHERE col IS NULL. Lo stesso vale per <>: usa IS NOT NULL.

Che differenza c'è tra IFNULL e COALESCE in SQLite?

IFNULL(a, b) accetta esattamente due argomenti e restituisce a, a meno che non sia nullo: in quel caso restituisce b. COALESCE(a, b, c, ...) accetta quanti argomenti vuoi e restituisce il primo non nullo. IFNULL è una scorciatoia per due valori; COALESCE è il caso generale ed è portabile su quasi tutti i database SQL.

NULL è uguale a una stringa vuota in SQLite?

No. NULL significa "nessun valore", mentre '' è una stringa di lunghezza zero, cioè un valore reale e conosciuto. '' IS NULL restituisce 0 (falso), e length('') vale 0 mentre length(NULL) è NULL. Se una colonna ammette entrambi, le tue query devono gestirli separatamente oppure normalizzare uno nell'altro.

Illustrazione dei linguaggi di programmazione di Coddy

Impara a programmare con Coddy

INIZIA