NULL ne se compare pas, et emporte les lignes avec lui
Exercice · niveau 2 · informatique (MP2I/MPI), chapitre 21 — Bases de données relationnelles et SQL
Énoncé
On considère la jointure externe du cours, où Dupont apparaît avec une valeur NULL. Que rend chacune de ces requêtes ?
-- (a)
SELECT e.nom FROM Eleve e LEFT JOIN Note n ON n.eleve = e.id
WHERE n.valeur = NULL;
-- (b)
SELECT e.nom FROM Eleve e LEFT JOIN Note n ON n.eleve = e.id
WHERE n.valeur IS NULL;
-- (c)
SELECT e.nom FROM Eleve e LEFT JOIN Note n ON n.eleve = e.id
WHERE NOT (n.valeur = 17);Corrigé
(a) Zéro ligne. Pas même celle de Dupont, dont la valeur est pourtant bien NULL. La comparaison n.valeur = NULL ne s'évalue ni à vrai ni à faux : elle s'évalue à inconnu, et le WHERE ne garde que les lignes où la condition est vraie. Vérifié : SELECT NULL = NULL rend NULL, et non .
(b) Une ligne : Dupont. C'est à cela que sert IS NULL, et c'est le seul moyen. SELECT NULL IS NULL rend bien .
(c) Quatre lignes : Alaoui, Benali, Benali, Cohen — et pas Dupont. C'est le vrai piège de l'exercice.
On lit « tous ceux qui n'ont pas », et l'on s'attend à voir Dupont, qui n'a effectivement pas . Mais pour lui, n.valeur = 17 vaut inconnu, et NOT d'inconnu vaut encore inconnu. La ligne est écartée.
| (avec inconnu) | `NOT`(…) | gardée ? | |
|---|---|---|---|
| vrai | faux | non | |
| faux | vrai | oui | |
| `NULL` | inconnu | inconnu | non |
La logique de SQL est à trois valeurs, et ni le tiers exclu ni la double négation n'y valent : et peuvent être fausses toutes les deux. Le chapitre chap:logique raisonnait à deux valeurs ; ici il y en a trois, et une condition qui « devrait » être exhaustive ne l'est pas.
La règle qu'on en tire : dès qu'une colonne peut valoir NULL, une négation dans le WHERE doit s'écrire explicitement
WHERE n.valeur <> 17 OR n.valeur IS NULL
faute de quoi on perd silencieusement des lignes — exactement le défaut que le cours signale à propos de JOIN contre LEFT JOIN, mais logé cette fois dans le WHERE.
Les autres exercices de ce chapitre Le cours du chapitre
Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.