Trois élèves n'ont pas d'adresse email. Les retrouver semble simple, et pourtant WHERE email = NULL ne renvoie rien. Cet article explique ce qu'est NULL et comment le tester avec IS NULL.
L'école veut envoyer un rappel aux familles des élèves qui n'ont pas encore communiqué d'adresse email. Il faut donc trouver les lignes où la colonne email est vide. La requête qui vient à l'esprit semble évidente. Elle ne renvoie pourtant rien du tout.
💡 Télécharge
mon-ecole-eleves.dbdans la sidebar, ouvre-la dans DB Browser for SQLite, puis va dans l'onglet Exécuter le SQL. Tape chaque requête dans la zone du haut et exécute-la avec ▶ ou Ctrl+Entrée.
À la fin de cet article, tu seras capable de :
NULL dans une base de données ;NULL, le nombre 0 et le texte vide '' ;WHERE email = NULL ne renvoie jamais rien ;IS NULL et IS NOT NULL ;NULL sans le vouloir ;NULL dans un tri.La base contient une table eleve, avec une ligne par élève. Pour la lire, on écrit une requête : SELECT (sélectionne) donne les colonnes à afficher, FROM (depuis) donne la table où les chercher.
Affiche les adresses email :
SELECT prenom, nom, email
FROM eleve;
prenom | nom | email
--------+-----------+------------------------
Lucas | Adam | lucas.adam@ecole.be
Emma | Bastin | emma.bastin@ecole.be
Noah | Charlier | NULL
Léa | Delvaux | lea.delvaux@ecole.be
Hugo | Englebert | hugo.englebert@ecole.be
Chloé | Fontaine | NULL
Nathan | Gérard | nathan.gerard@ecole.be
Manon | Hubert | manon.hubert@ecole.be
Louis | Istas | louis.istas@ecole.be
Camille | Jacques | NULL
Arthur | Kevers | arthur.kevers@ecole.be
Sarah | Lambert | sarah.lambert@ecole.be
Pour Noah, Chloé et Camille, la case affiche NULL. Ce n'est pas une adresse qui s'écrirait N-U-L-L. C'est une marque qui signifie : ici, il n'y a pas de valeur. L'école ne connaît pas leur adresse.
📖 Nouvelle notion : NULL
NULLest la marque qu'une base de données place dans une case quand la valeur est absente ou inconnue. Ce n'est pas une valeur comme les autres : ce n'est ni le nombre zéro, ni un texte vide. Le mot vient de l'anglais null, qui veut dire nul, aucun.En anglais : 🇬🇧 null value.
ℹ️ Toutes les colonnes n'acceptent pas
NULL. Dans l'onglet Structure de la base, les colonnesnometprenomportent la mentionNOT NULL(pas nul) : la base refuse un élève sans nom. La colonne
La colonne absences contient des zéros. Cherche-les :
SELECT prenom, nom, absences
FROM eleve
WHERE absences = 0;
prenom | nom | absences
-------+----------+---------
Emma | Bastin | 0
Chloé | Fontaine | 0
Manon | Hubert | 0
Sarah | Lambert | 0
Pour Emma, l'école sait quelque chose : elle n'a jamais été absente. Zéro est une information connue.
Cherche maintenant un email égal au texte vide, deux apostrophes collées :
SELECT prenom, nom, email
FROM eleve
WHERE email = '';
prenom | nom | email
-------+-----+------
Aucune ligne. Les trois cases vides ne contiennent pas un texte de zéro caractère : elles ne contiennent rien du tout.
| Écriture | Signification | Exemple |
|---|---|---|
0 |
un nombre connu, qui vaut zéro | Emma n'a aucune absence |
'' |
un texte connu, qui ne contient aucun caractère | quelqu'un a encodé une adresse vide |
NULL |
aucune valeur : on ne sait pas | l'adresse de Noah n'a jamais été communiquée |
Pour trouver les élèves sans adresse, la requête naturelle est celle-ci :
SELECT prenom, nom, email
FROM eleve
WHERE email = NULL;
prenom | nom | email
-------+-----+------
Aucune ligne, et aucun message d'erreur. La requête est valide, mais elle ne renverra jamais rien, quelle que soit la table.
Pour comprendre, pose la question à voix haute pour Noah : « est-ce que son adresse, qu'on ne connaît pas, est égale à une valeur qu'on ne connaît pas ? ». La seule réponse honnête est : on ne sait pas. Et c'est exactement ce que répond SQLite.
Tu peux le vérifier. Exécute ces trois comparaisons, sans table :
SELECT NULL = NULL AS test1,
'a' = 'a' AS test2,
NULL <> 'a' AS test3;
test1 | test2 | test3
------+-------+------
NULL | 1 | NULL
SQLite affiche 1 pour vrai et 0 pour faux. La comparaison 'a' = 'a' est vraie. Mais toute comparaison avec NULL donne NULL : ni vrai, ni faux, inconnu.
Or WHERE ne garde que les lignes pour lesquelles la condition est vraie. Une condition inconnue n'est pas vraie, donc la ligne est écartée.
🧠 Toute comparaison avec
NULL(=,<>,<,>,LIKE…) donne un résultat inconnu.WHEREécarte les lignes dont la condition est inconnue. C'est pour cela queWHERE email = NULLne renvoie jamais rien.
Puisque = ne peut pas tester NULL, SQL propose un opérateur spécial : IS NULL, qui veut dire est nul.
SELECT prenom, nom, email
FROM eleve
WHERE email IS NULL;
prenom | nom | email
--------+----------+------
Noah | Charlier | NULL
Chloé | Fontaine | NULL
Camille | Jacques | NULL
Les trois élèves sont enfin là. IS NULL ne compare pas deux valeurs : il pose une autre question, « cette case est-elle vide ? », à laquelle la réponse est toujours oui ou non.
📖 Nouvelle notion : IS NULL et IS NOT NULL
IS NULL(est nul) est vrai quand la case ne contient aucune valeur.IS NOT NULL(n'est pas nul) est vrai quand la case contient une valeur, quelle qu'elle soit. Ce sont les seuls moyens fiables de tester l'absence de valeur : on n'écrit jamais= NULL.En anglais : 🇬🇧 IS NULL, littéralement is null.
L'inverse, IS NOT NULL, retrouve les élèves qui ont une adresse :
SELECT prenom, nom, email
FROM eleve
WHERE email IS NOT NULL;
prenom | nom | email
-------+-----------+------------------------
Lucas | Adam | lucas.adam@ecole.be
Emma | Bastin | emma.bastin@ecole.be
Léa | Delvaux | lea.delvaux@ecole.be
Hugo | Englebert | hugo.englebert@ecole.be
Nathan | Gérard | nathan.gerard@ecole.be
Manon | Hubert | manon.hubert@ecole.be
Louis | Istas | louis.istas@ecole.be
Arthur | Kevers | arthur.kevers@ecole.be
Sarah | Lambert | sarah.lambert@ecole.be
IS NULL se combine avec d'autres conditions, comme n'importe quelle condition. Voici les élèves sans adresse qui ont plus de 3 absences, et dont il faudrait contacter la famille autrement :
SELECT prenom, nom, email
FROM eleve
WHERE email IS NULL
AND absences > 3;
prenom | nom | email
--------+----------+------
Noah | Charlier | NULL
Camille | Jacques | NULL
Le piège de NULL ne se limite pas à = NULL. Cherche tous les élèves sauf Lucas Adam, en te servant de son adresse :
SELECT prenom, nom, email
FROM eleve
WHERE email <> 'lucas.adam@ecole.be';
prenom | nom | email
-------+-----------+------------------------
Emma | Bastin | emma.bastin@ecole.be
Léa | Delvaux | lea.delvaux@ecole.be
Hugo | Englebert | hugo.englebert@ecole.be
Nathan | Gérard | nathan.gerard@ecole.be
Manon | Hubert | manon.hubert@ecole.be
Louis | Istas | louis.istas@ecole.be
Arthur | Kevers | arthur.kevers@ecole.be
Sarah | Lambert | sarah.lambert@ecole.be
Huit lignes au lieu de onze. Noah, Chloé et Camille ont disparu. Leur adresse n'est pas celle de Lucas, bien sûr, mais SQLite ne peut pas l'affirmer : comparer NULL à une adresse donne un résultat inconnu, et la ligne est écartée.
Pour les récupérer, il faut les demander explicitement :
SELECT prenom, nom, email
FROM eleve
WHERE email <> 'lucas.adam@ecole.be'
OR email IS NULL;
prenom | nom | email
--------+-----------+------------------------
Emma | Bastin | emma.bastin@ecole.be
Noah | Charlier | NULL
Léa | Delvaux | lea.delvaux@ecole.be
Hugo | Englebert | hugo.englebert@ecole.be
Chloé | Fontaine | NULL
Nathan | Gérard | nathan.gerard@ecole.be
Manon | Hubert | manon.hubert@ecole.be
Louis | Istas | louis.istas@ecole.be
Camille | Jacques | NULL
Arthur | Kevers | arthur.kevers@ecole.be
Sarah | Lambert | sarah.lambert@ecole.be
⚠️ Une condition sur une colonne qui peut contenir
NULLécarte ces lignes en silence, même avec<>ouNOT LIKE. Pose-toi toujours la question : « et les cases vides, je les veux ou pas ? ».
Trie les élèves par adresse email :
SELECT prenom, nom, email
FROM eleve
ORDER BY email;
prenom | nom | email
--------+-----------+------------------------
Noah | Charlier | NULL
Chloé | Fontaine | NULL
Camille | Jacques | NULL
Arthur | Kevers | arthur.kevers@ecole.be
Emma | Bastin | emma.bastin@ecole.be
Hugo | Englebert | hugo.englebert@ecole.be
Léa | Delvaux | lea.delvaux@ecole.be
Louis | Istas | louis.istas@ecole.be
Lucas | Adam | lucas.adam@ecole.be
Manon | Hubert | manon.hubert@ecole.be
Nathan | Gérard | nathan.gerard@ecole.be
Sarah | Lambert | sarah.lambert@ecole.be
Dans un tri croissant, SQLite place les NULL en premier, comme s'ils étaient plus petits que toutes les valeurs. Avec ORDER BY email DESC, ils passent en dernier.
ℹ️ Tous les logiciels ne font pas ce choix. PostgreSQL, par exemple, place les
NULLà la fin d'un tri croissant. Si leur place compte, vérifie-la.
Pour chaque exercice, écris la requête, exécute-la, puis vérifie que le résultat répond vraiment à la question.
Écris une requête qui affiche le prénom et le nom :
Pour chaque situation, indique ce qu'il faudrait enregistrer dans la case : 0, '' ou NULL. Justifie en une phrase.
Sans exécuter, écris combien de lignes renvoie chaque requête. Exécute ensuite pour vérifier.
-- a)
SELECT nom FROM eleve WHERE email = NULL;
-- b)
SELECT nom FROM eleve WHERE email IS NULL;
-- c)
SELECT nom FROM eleve WHERE email <> 'emma.bastin@ecole.be';
-- d)
SELECT nom FROM eleve WHERE email NOT LIKE '%.a%';
-- e)
SELECT nom FROM eleve WHERE email = 'NULL';
Chacune de ces requêtes ne répond pas à la question posée. Pour chacune : exécute-la, observe, explique ce qui ne va pas, puis corrige-la.
-- a) Les élèves sans adresse email
SELECT prenom, nom FROM eleve WHERE email = NULL;
-- b) Les élèves sans adresse email
SELECT prenom, nom FROM eleve WHERE email = 'NULL';
-- c) Tous les élèves sauf Lucas Adam (il y en a onze)
SELECT prenom, nom FROM eleve WHERE email <> 'lucas.adam@ecole.be';
-- d) Les élèves qui ont une adresse email
SELECT prenom, nom FROM eleve WHERE email <> NULL;
NULL marque une valeur absente ou inconnue. Ce n'est ni 0, ni le texte vide ''.NULL donne un résultat inconnu, et WHERE écarte les lignes dont la condition est inconnue.WHERE email = NULL ne renvoie jamais rien : on écrit WHERE email IS NULL.IS NOT NULL retrouve les cases qui contiennent une valeur.email <> '…' écarte aussi les NULL : ajoute OR email IS NULL si tu les veux.NULL arrivent en premier dans un tri croissant.Tu sais maintenant filtrer, trier et gérer les cases vides. Pour ne garder que les premières lignes d'un résultat, comme « les trois élèves les plus absents », passe à Limiter le nombre de lignes avec LIMIT.