Avancé · 20 min
NULL et logique à trois valeurs : le piège le plus fréquent
NULL n'est ni vrai ni faux : comprendre IS NULL, COALESCE et le piège de NOT IN avec des NULL.
Contexte
Une valeur manquante (une ville non renseignée, un paiement jamais enregistré) n'est pas « vide » en SQL : elle est NULL, et NULL casse les réflexes habituels du OUI/NON. C'est la première vraie source d'erreurs sur des données réelles — bien après avoir maîtrisé SELECT et WHERE.
Explication
SQL utilise une logique à trois valeurs : VRAI, FAUX, et INCONNU (le résultat de toute comparaison impliquant NULL). colonne = NULL ne vaut jamais vrai — même sur la ligne où colonne est NULL — parce que « est-ce égal à une valeur qu'on ne connaît pas ? » n'a pas de réponse. Il faut IS NULL / IS NOT NULL, pas = / !=.
Syntaxe :
SELECT * FROM une_table WHERE col1 IS NULL;
SELECT COALESCE(col1, 'valeur par défaut') FROM une_table;
Pièges à connaître :
WHERE colonne != NULLou= NULLne renvoie jamais rien (INCONNU n'est ni gardé par WHERE, ni par HAVING).NOT IN (sous-requête)renvoie tout inconnu, donc silencieusement aucune ligne, si la sous-requête contient ne serait-ce qu'un seul NULL — préférerNOT EXISTSdès qu'une colonne de la sous-requête peut être NULL.COALESCE(a, b, c, ...)renvoie la première valeur non NULL de la liste : pratique pour un affichage avec valeur de repli.
Exemple guidé
Sur la base boutique, certains clients n'ont pas de ville renseignée à l'inscription :
SELECT prenom, nom, COALESCE(ville, 'Non renseignée') AS ville
FROM clients
ORDER BY date_inscription DESC, nom
LIMIT 5;
COALESCE affiche 'Non renseignée' à la place d'un NULL brut, sans changer les autres lignes. Autre cas fréquent : une commande marquée « payee » sans aucune ligne dans paiements (incohérence de caisse) se détecte avec un LEFT JOIN puis WHERE ... IS NULL — le même schéma que pour repérer une absence de correspondance, vu dans les jointures.
À retenir
NULL n'est ni vrai ni faux : toute comparaison directe (=, !=) avec NULL renvoie INCONNU, jamais vrai. IS NULL / IS NOT NULL pour tester. COALESCE pour une valeur de repli à l'affichage. NOT IN + une sous-requête pouvant contenir NULL = piège classique (préférer NOT EXISTS).