Immagina di lavorare su un database universitario e devi trovare gli studenti che seguono certi corsi. Tipo "Programmazione", "Matematica" e "Fisica". Ovviamente puoi scrivere una query lunga con un sacco di condizioni tipo:
SELECT *
FROM students
WHERE course = 'Programmazione'
OR course = 'Matematica'
OR course = 'Fisica';
Ma dai, diciamoci la verità. Scrivere queste robe è noioso e non è proprio elegante. Per fortuna c'è l'operatore IN, che ti permette di scrivere la stessa query in modo compatto e risparmiare tempo:
SELECT *
FROM students
WHERE course IN ('Programmazione', 'Matematica', 'Fisica');
Sembra magia, vero? Invece di mille condizioni con OR dici semplicemente a SQL di cercare i valori in questa lista. E se vuoi controllare che un valore non sia nella lista, usi NOT IN — Cerca tutto quello che non è in questa lista.
Sintassi dell'operatore IN
Ecco la sintassi generale di IN:
SELECT colonne
FROM tabella
WHERE colonna IN (valore1, valore2, valore3, ...);
Ora vediamo qualche esempio.
Esempio 1: Studenti che seguono più corsi
Supponiamo di avere la tabella students:
| id | name | course |
|---|---|---|
| 1 | Anna | Programmazione |
| 2 | Mello | Fisica |
| 3 | Kate | Matematica |
| 4 | Dan | Chimia |
| 5 | Olly | Biologia |
Vogliamo trovare tutti gli studenti che studiano "Programmazione", "Matematica" o "Fisica". Usiamo IN:
SELECT name, course
FROM students
WHERE course IN ('Programmazione', 'Matematica', 'Fisica');
Risultato:
| name | course |
|---|---|
| Anna | Programmazione |
| Mello | Fisica |
| Kate | Matematica |
Come vedi, l'operatore IN ha reso tutto molto più semplice. Non serve scrivere mille condizioni con OR, basta mettere la lista dei valori che ti interessano.
Esempio 2: Studenti che non seguono certi corsi
Ora, supponiamo che vuoi trovare gli studenti che non studiano "Programmazione", "Matematica" e "Fisica". Qui ci aiuta NOT IN:
SELECT name, course
FROM students
WHERE course NOT IN ('Programmazione', 'Matematica', 'Fisica');
Risultato:
| name | course |
|---|---|
| Dan | Chimia |
| Olly | Biologia |
Quindi, NOT IN restituisce tutte le righe dove il valore della colonna course non è nella lista specificata.
Uso di IN e NOT IN con subquery
Gli operatori IN e NOT IN sono super utili quando devi confrontare dati tra due tabelle. Per esempio, abbiamo due tabelle:
Tabella students:
| id | name | course_id |
|---|---|---|
| 1 | Anna | 101 |
| 2 | Mello | 102 |
| 3 | Kate | 103 |
| 4 | Dan | 104 |
Tabella courses:
| id | name |
|---|---|
| 101 | Programmazione |
| 102 | Fisica |
| 103 | Matematica |
| 105 | Chimia |
Immagina di dover trovare gli studenti iscritti a corsi che esistono nella tabella courses. Qui ci aiuta una subquery con IN:
SELECT name
FROM students
WHERE course_id IN (
SELECT id
FROM courses
);
Questa query funziona così: la subquery SELECT id FROM courses restituisce la lista di tutti gli id dei corsi. Poi IN controlla se course_id è in quella lista.
Risultato:
| name |
|---|
| Anna |
| Mello |
| Kate |
Perché manca Dan? Perché il suo course_id (104) non esiste nella tabella courses.
Particolarità con NULL
L'operatore IN ha una particolarità importante: se nella lista dei valori c'è NULL, questo può influenzare il risultato della query. Vediamo un esempio.
Tabella grades:
| student_id | course_id | grade |
|---|---|---|
| 1 | 101 | A |
| 2 | 102 | NULL |
| 3 | 103 | B |
Una query che cerca studenti con voto in ('A', 'B', 'C') potrebbe essere così:
SELECT student_id
FROM grades
WHERE grade IN ('A', 'B', 'C');
Risultato:
| student_id |
|---|
| 1 |
| 3 |
La riga con NULL nella colonna grade viene ignorata, perché NULL non fa parte di nessuna lista.
Ora immagina di usare NOT IN. Tipo:
SELECT student_id
FROM grades
WHERE grade NOT IN ('A', 'B', 'C');
Ti aspetti di vedere la riga con student_id = 2, ma il risultato sarà vuoto! Perché? Perché NULL viene confrontato con ogni valore della lista e il risultato è sempre sconosciuto (UNKNOWN). Questo comportamento può confondere, quindi quando usi NOT IN occhio alle colonne con NULL. Meglio aggiungere un controllo esplicito per NULL:
SELECT student_id
FROM grades
WHERE grade NOT IN ('A', 'B', 'C')
OR grade IS NULL;
Risultato:
| student_id |
|---|
| 2 |
Consigli per usare IN e NOT IN
Usa IN per rendere il tuo SQL più leggibile
Se devi controllare se una colonna è in una certa lista di valori, meglio usare IN invece di mille condizioni con OR.
Fai attenzione a NOT IN e NULL
Se nei dati ci sono colonne con NULL, possono causare risultati strani. Meglio gestire NULL in modo esplicito quando usi NOT IN.
Usa gli indici per velocizzare le subquery
Se IN viene usato con una subquery, assicurati che la colonna nella subquery sia indicizzata, così eviti problemi di performance.
Esempio di problema reale
Immagina di lavorare su un sistema di e-commerce. Hai le tabelle orders e users. Vuoi trovare tutti gli utenti che non hanno mai fatto un ordine.
Tabella users:
| id | name |
|---|---|
| 1 | Anna |
| 2 | Mello |
| 3 | Kate |
| 4 | Dan |
Tabella orders:
| id | user_id | total |
|---|---|---|
| 1 | 1 | 500 |
| 2 | 3 | 300 |
Usiamo NOT IN per risolvere il problema:
SELECT name
FROM users
WHERE id NOT IN (
SELECT user_id
FROM orders
);
Risultato:
| name |
|---|
| Mello |
| Dan |
Questa query funziona così: prima la subquery SELECT user_id FROM orders restituisce gli id di tutti gli utenti che hanno fatto ordini (1 e 3). Poi NOT IN li esclude, lasciando solo chi non ha mai ordinato (Mello e Dan).
GO TO FULL VERSION