Polarys

Écrire sans se tromper

NULL, dates et comparaisons piégeuses

NULL n'est pas une valeur

C'est l'absence de valeur, et cette différence produit les erreurs les plus discrètes de SQL : la requête s'exécute, ne signale rien, et renvoie un résultat faux.

SELECT * FROM client WHERE email = NULL;    -- ne renvoie JAMAIS rien
SELECT * FROM client WHERE email IS NULL;   -- correct

Toute comparaison avec NULL donne « inconnu », pas « vrai » ni « faux ». Un filtre sur inconnu ne garde aucune ligne.

Conséquence moins connue et plus vicieuse :

SELECT * FROM commande WHERE statut <> 'annulee';

Cette requête exclut aussi les lignes dont le statut est nul. Si l'on voulait « tout sauf les annulées », il faut l'écrire :

WHERE statut IS DISTINCT FROM 'annulee'
-- ou : WHERE (statut <> 'annulee' OR statut IS NULL)

NULL dans les calculs et les agrégats

Toute opération arithmétique avec NULL donne NULL : prix + remise vaut NULL si la remise est nulle, et non le prix seul. COALESCE(remise, 0) remplace le nul par une valeur neutre.

Rappel de la leçon sur l'agrégation : SUM et AVG ignorent les nuls, COUNT(*) non. Un total qui paraît trop bas vient souvent de là.

Les dates, trois pièges

Le fuseau horaire. Une date stockée sans fuseau ne dit pas à quel moment elle correspond. Deux colonnes remplies par des systèmes différents peuvent être décalées de plusieurs heures sans que rien ne le signale. Préférez un type avec fuseau, et stockez en temps universel.

La borne de fin. Une comparaison entre deux dates sur une colonne qui porte aussi l'heure exclut presque toute la dernière journée :

WHERE date_commande BETWEEN '2026-01-01' AND '2026-01-31'
-- exclut tout ce qui suit 2026-01-31 00:00:00

La forme sûre :

WHERE date_commande >= '2026-01-01' AND date_commande < '2026-02-01'

Elle est correcte quelle que soit la précision stockée, et elle reste utilisable par un index.

La fonction appliquée à la colonne. WHERE YEAR(date_commande) = 2026 empêche l'usage de l'index et lit toute la table. La forme par intervalle ci-dessus fait le même travail sans ce coût.

Les textes

La comparaison peut être sensible ou non à la casse et aux accents selon la configuration de la base. Ne le supposez pas : vérifiez sur votre base.

Et les espaces en fin de chaîne, invisibles à l'oeil, font échouer une égalité qui semble évidente : TRIM sur les données importées évite des heures de perplexité.

À retenir

IS NULL, jamais = NULL. Un <> exclut les nuls, pensez-y. Sur les dates, un intervalle borné à droite par le début du mois suivant, jamais une fonction sur la colonne. Et méfiez-vous des espaces invisibles.

Quiz de validation

Quiz - 3 questions

1. Que renvoie WHERE email = NULL ?

2. WHERE statut <> 'annulee' : que se passe-t-il pour les lignes dont le statut est nul ?

3. Quelle forme de filtre sur une période est à la fois correcte et indexable ?

Suis ta progression

Crée un compte gratuit pour suivre ta progression et accéder à toutes les leçons.