Condizioni avanzate in SQL

Nella lezione precedente abbiamo visto come utilizzare la clausola WHERE per filtrare i dati in base a una o più condizioni. Abbiamo visto come usare gli operatori di confronto, come =, >, < e <>, e a combinare più condizioni con AND, OR e NOT.

Questi strumenti sono sufficienti per molte situazioni, ma SQL mette a disposizione anche operatori che permettono di creare condizioni più flessibili e specifiche. Possiamo, ad esempio, verificare se un valore appartiene a un insieme, controllare se si trova all'interno di un intervallo oppure cercare del testo che segue un determinato modello.

In questa lezione vedremo IN, NOT IN, BETWEEN, LIKE e i caratteri jolly, ma anche come SQL gestisce i valori sconosciuti e a cosa serve NULL.

Insiemi e intervalli

Quando utilizziamo WHERE, può capitare di voler verificare se un valore corrisponde o meno a uno tra diversi valori possibili, oppure sia compreso tra due valori. In questi casi possiamo utilizzare i seguenti operatori:

OperatoreDescrizione
IN () Appartiene ad un insieme di valori.
NOT IN () Non appartiene ad un insieme di valori.
BETWEEN È incluso nell'intervallo.

Guardiamoli in dettaglio.

Operatore IN

IN permette di verificare se un valore appartiene a un insieme di valori.

Per esempio, supponiamo di voler selezionare gli utenti che vivono a Milano, Roma o Torino:

SELECT * FROM utenti
WHERE citta IN ('Milano', 'Roma', 'Torino');

Questa query è equivalente a scrivere:

SELECT * FROM utenti
WHERE citta = 'Milano' OR citta = 'Roma' OR citta = 'Torino';

IN rende la condizione più breve e leggibile, soprattutto quando dobbiamo confrontare un valore con molti valori diversi.

Possiamo utilizzare IN anche con i numeri. Per esempio:

SELECT * FROM utenti
WHERE eta IN (30, 40, 50);

In questo caso verranno restituite soltanto le persone che hanno esattamente l'età di 30, 40 e 50 anni. 

Operatore NOT IN

L'operatore NOT IN permette di verificare che un valore non appartenga all'insieme indicato.

Ad esempio, se vogliamo solo gli utenti che non vivono né a Milano né a Roma:

SELECT * FROM utenti
WHERE citta NOT IN ('Milano', 'Roma');

Operatore BETWEEN

Quando vogliamo verificare se un valore si trova all'interno di un intervallo, possiamo utilizzare BETWEEN.

La sintassi è: WHERE colonna BETWEEN valore_minimo AND valore_massimo;

Ad esempio:

SELECT * FROM utenti
WHERE eta BETWEEN 20 AND 50;

La query seleziona gli utenti con un'età compresa tra 20 e 50.

Nota: BETWEEN include entrambi gli estremi. Quindi, con BETWEEN 20 AND 50, vengono inclusi anche 20 e 50.

La condizione dell'esempio precedente è equivalente a:

SELECT * FROM utenti
WHERE eta >= 20 AND eta <= 50;

Operatore LIKE

Gli operatori di confronto che abbiamo visto finora permettono di verificare se un valore corrisponde esattamente a un altro valore. Quando invece vogliamo cercare un testo contenuto all'interno di un valore, possiamo utilizzare LIKE.

Per usare LIKE, dobbiamo conoscere due caratteri jolly importanti:

CarattereDescrizione
% Corrisponde a zero o più caratteri.
_ Corrisponde a un singolo carattere.

Vediamoli in dettaglio.

Carattere "%"

Il carattere jolly % rappresenta zero o più caratteri

Ad esempio, possiamo cercare tutti gli utenti il cui nome inizia con la lettera "A":

SELECT * FROM utenti WHERE nome LIKE 'A%';

Di conseguenza, la condizione può corrispondere a valori come: Andrea, Alice, A...

Possiamo utilizzare % anche alla fine, per cercare i nomi che terminano con "a":

SELECT * FROM utenti WHERE nome LIKE '%a';

Se invece utilizziamo % all'inizio e alla fine, cerchiamo i valori che contengono il testo in qualsiasi posizione:

SELECT * FROM utenti WHERE nome LIKE '%arc%';

Carattere "_"

Il carattere _ è un altro carattere jolly, ma ha un comportamento diverso da %: rappresenta un singolo carattere.

Per esempio:

SELECT * FROM utenti WHERE nome LIKE 'M_rc_';

Nell'esempio, WHERE richiede un nome di cinque caratteri che inizi con M, abbia rc nelle posizioni successive e un altro carattere alla fine.

Valori nulli e risultati sconosciuti

Finora abbiamo ragionato sulle condizioni SQL come se potessero avere soltanto due risultati: vero o falso. Nella realtà, SQL utilizza una logica diversa, perché una condizione può avere tre possibili risultati:

  • TRUE, quando la condizione è vera.
  • FALSE, quando la condizione è falsa.
  • UNKNOWN, quando il risultato non può essere determinato.

Prendiamo come esempio la seguente condizione:

WHERE eta > 18

Se un utente non ha impostato un'età, il valore presente nel database sarà eta=NULL per quell'utente. Quando viene eseguita la query, SQL non può stabilire se NULL sia maggiore di 18. Il risultato della condizione diventa quindi UNKNOWN.

Quando utilizziamo una condizione con WHERE, vengono restituite solamente le righe per cui la condizione risulta TRUE. Le condizioni che producono FALSE o UNKNOWN vengono escluse dal risultato.

Gestire i valori NULL

Nei database può capitare che una colonna non contenga alcun valore. In SQL questa situazione viene rappresentata con NULL.

NULL non significa semplicemente zero, una stringa vuota o un valore specifico. Indica che il valore è assente o sconosciuto. Per esempio, potremmo avere una tabella utenti in cui alcuni utenti non hanno ancora indicato il proprio numero di telefono.

In questo caso, per cercare gli utenti per cui il numero di telefono è assente, non possiamo utilizzare:

WHERE telefono = NULL

Questa condizione non funziona come sembrerebbe. SQL non considera NULL come un valore con cui effettuare un normale confronto. Il risultato di telefono = NULL è UNKNOWN, non TRUE. Di conseguenza, WHERE non restituisce quelle righe.

Per verificare se una colonna contiene NULL, dobbiamo utilizzare l'operatore IS NULL:

SELECT * FROM utenti
WHERE telefono IS NULL;

Questa query restituisce gli utenti per i quali il numero di telefono è assente.

Per ottenere invece le righe in cui è presente un valore, possiamo utilizzare IS NOT NULL:

SELECT * FROM utenti
WHERE telefono IS NOT NULL;

Prova!Completa gli spazi vuoti con il testo appropriato.
-- Seleziona i nomi non nell'elenco
SELECT nome FROM utenti
WHERE nome ('Andrea', 'Marco');

Prova! Scegli l'opzione corretta tra quelle elencate.
-- Cerca tutti i nomi che iniziano con N
SELECT nome FROM utenti
WHERE nome __________;