Torna all'elenco degli articoli Articoli
Tempo di lettura: 5 minuti

Capire l'uso di NULL nella logica a tre valori di SQL

I NULL sono necessari nei database relazionali e imparare a usarli è fondamentale per il successo dell'SQL. Tuttavia, anche i NULL devono essere gestiti con cura, come spieghiamo in questo post.

Nei database relazionali, non sempre abbiamo un valore da inserire in una colonna. Ad esempio, supponiamo di avere una tabella chiamata "persone" con le colonne "nome_nome", "cognome", "data_nascita" e "data_matrimonio". Quale valore memorizzeremo nella colonna "data_matrimonio" per le persone singole? In questo caso, la colonna non può avere un valore perché i single non sono sposati. Abbiamo bisogno di un modo per indicare che non abbiamo un valore per questa colonna. Fortunatamente esiste un modo: il valore NULL, ampiamente utilizzato nei database relazionali.

I NULL possono essere applicati a qualsiasi tipo di dati: interi, date, VARCHAR o qualsiasi altro tipo di colonna. Tuttavia, occorre prestare attenzione quando si creano calcoli o espressioni contenenti uno o più operatori con un valore NULL. Vediamo perché.

NULL e logica a tre valori

Il motivo per cui i NULL possono a volte creare confusione ha a che fare con una cosa chiamata logica a tre valori. Mentre la logica binaria o booleana ha due valori ("vero" e "falso"), la logica a tre valori (abbreviata in 3VL e nota anche come logica ternaria) ha un valore aggiuntivo: "sconosciuto".

Illustriamo 3VL con un semplice scenario. Supponiamo di voler ottenere i nomi dei dipendenti che guadagnano più di 1.200 euro al mese. La tabella employee tabella ha questo aspetto:

First Name Last Name Salary Bonus
John Smith 1000 500
Mary Smith 1000 1500
Peter White 1800 NULL
Nick Perry 1000 NULL

Proviamo a eseguire la seguente interrogazione:

SELECT * FROM employee WHERE bonus + salary > 1200;

Il risultato è:

First Name Last Name Salary Bonus
John Smith 1000 500
Mary Smith 1000 1500

Dovremmo vedere tre record nell'insieme dei risultati, ma ce ne sono solo due. Perché Peter White non è incluso? Il motivo è legato al valore NULL della colonna bonus. In SQL, ogni operazione aritmetica che include un operando con valore NULL restituisce un risultato NULL.

Quindi, tenendo presente questo aspetto, guardate come è stato valutato il record di Peter White:

1800 + NULL > 1200

In altre parole, lo stipendio di Peter (1.800) e il suo bonus (NULL) si sommano a NULL. Possiamo ridurre questa condizione a :

NULL > 1200

Quindi NULL è maggiore di 1.200? Ricordiamo che NULL rappresenta un valore inesistente, il che significa che non abbiamo nulla da confrontare con 1.200: non possiamo sapere se questa affermazione è vera o falsa. Ecco come funziona la logica a tre valori. Quando in una condizione c'è un valore NULL, il risultato di questa condizione sarà "sconosciuto".

Come affrontare la logica a tre valori nelle query SQL

Per capire come funziona la logica a tre valori, esaminiamo il processo passo per passo. Innanzitutto, si pensi a come vengono filtrati i record nella clausola WHERE. Solo i record che hanno valore "vero" nella clausola WHERE fanno parte dell'insieme dei risultati della query. I record con valore "falso" o "sconosciuto" non fanno parte del risultato. Ecco perché il record di Peter White è stato escluso dai risultati della query precedente. Il suo stipendio totale è valutato "sconosciuto" nella clausola WHERE; "1800 + NULL > 1200" è "sconosciuto" perché non possiamo sapere cosa sia NULL.

Anche le tabelle AND, OR e NOT sono importanti nella logica a tre valori, quindi le esamineremo singolarmente e vedremo come si calcolano. Cominciamo con la tabella NOT:

Value NOT Result
True False
False True
Unknown Unknown

Vediamo poi la tabella AND:

AND True False Unknown
True True False Unknown
False False False False
Unknown Unknown False Unknown

Analizziamo perché "falso" E "sconosciuto" equivalgono a "falso". Un solo "falso" è sufficiente a rendere "falso" l'intero risultato di un'operazione AND. Questo è vero indipendentemente dal fatto che il secondo valore sia "vero", "falso" o "sconosciuto".

Infine, abbiamo la tabella OR:

OR True False Unknown
True True True True
False True False Unknown
Unknown True Unknown Unknown

Proviamo a eseguire una query con l'operatore OR:

SELECT * FROM employee WHERE salary < 1500 OR bonus > 200 

Il risultato è il seguente:

First Name Last Name Salary Bonus
John Smith 1000 500
Mary Smith 1000 1500
Nick Perry 1000 NULL

Si noti che un record contenente un valore NULL nella colonna "bonus" viene mostrato nel risultato, mentre l'altro record NULL non viene mostrato. Il motivo è l'operatore OR. Dal momento che la condizione stipendio < 1500 è vera, non è necessario valutare la condizione bonus > 200.

Come gestire la variabile sconosciuta

A volte è possibile evitare di utilizzare valori "sconosciuti" nelle condizioni WHERE convertendo i valori NULL in altri valori (come 0) utilizzando la funzione COALESCE(). Considerate gli esempi precedenti. Se si convertisse ogni NULL in "0" prima di confrontare il valore nella condizione WHERE, si otterrebbero risultati diversi da quelli mostrati sopra. Tuttavia, questa conversione può essere possibile o meno, a seconda della semantica della query. Facciamo comunque un tentativo e vediamo cosa succede.

SELECT * FROM employee WHERE coalesce(bonus,0) > 200 OR salary < 1500

La query genererà solo risultati "veri" o "falsi". In questo caso, verrà applicata la logica a due valori.

Supponiamo di ricevere un ordine che prevede un aumento di stipendio del 5% per i dipendenti che guadagnano meno di 1.600 euro al mese. Come scrivere questa query? Proviamo:

UPDATE employee
SET salary = salary *1.05
WHERE salary + bonus <= 1600

Ecco i risultati:

First Name Last Name Salary Bonus
John Smith 1050 500
Mary Smith 1000 1500
Peter White 1800 NULL
Nick Perry 1000 NULL

Aspettate un attimo: lo stipendio di Nick non è cambiato! Non è giusto! Ancora una volta, il risultato "sconosciuto" della condizione "stipendio + bonus <= 1600" per il record di Nick causa un problema.

Il secondo tentativo va meglio:

UPDATE employee
SET salary = salary *1.05
WHERE salary + coalesce(bonus,0) <= 1600

Come possiamo vedere nel risultato della query seguente, lo stipendio di entrambi i record (John e Nick) è stato modificato.

First Name Last Name Salary Bonus
John Smith 1050 500
Mary Smith 1000 1500
Peter White 1800 NULL
Nick Perry 1050 NULL

Provate voi stessi!

Ci possono essere molte clausole WHERE diverse che danno come risultato "sconosciuto" o "falso". Perché non provare da soli alcune query SQL e vedere quali restituiscono valori "veri", "falsi" o "sconosciuti"? LearnSQL.it può insegnarvi tutto sulla clausola WHERE e sulle sue condizioni. Provatelo gratuitamente!