NULL en SQL est l'une des notions les plus mal comprises par les développeurs et les data analysts. Contrairement à un zéro ou à une chaîne vide, NULL représente l'absence totale de valeur — et cette distinction change radicalement la façon dont vos requêtes se comportent. Ignorer ce principe mène à des résultats faux, des jointures incomplètes et des bugs difficiles à tracer en production.
Dans cet article, vous allez comprendre ce qu'est réellement NULL, comment l'identifier, comment le filtrer et comment le remplacer proprement. Que vous passiez un test technique ou que vous travailliez sur un pipeline de données, maîtriser NULL est non-négociable.
📌 Ce qu'il faut retenir
- NULL n'est pas égal à 0, ni à une chaîne vide : c'est l'absence de donnée
- Toute comparaison avec NULL renvoie UNKNOWN, jamais TRUE ni FALSE
IS NULLetIS NOT NULLsont les seuls opérateurs fiables pour tester NULLCOALESCEetNULLIFpermettent de remplacer ou de produire des NULL proprement
Ce que NULL signifie vraiment en SQL
NULL représente une valeur inconnue ou inapplicable. Ce concept vient de l'algèbre relationnelle définie par Edgar F. Codd dans les années 1970. Le standard SQL ISO intègre cette logique dite ternaire : une condition peut être TRUE, FALSE ou UNKNOWN.
Quand vous écrivez WHERE age = NULL, la condition retourne UNKNOWN — et non FALSE. Le moteur SQL n'inclut donc aucune ligne, même celles où age vaut effectivement NULL. C'est le piège numéro 1 rencontré par les candidats lors des tests techniques.
Pour tester la présence de NULL, vous devez utiliser IS NULL ou IS NOT NULL, jamais = NULL ni <> NULL.
-- Incorrect
SELECT * FROM utilisateurs WHERE email = NULL;
-- Correct
SELECT * FROM utilisateurs WHERE email IS NULL;
La logique ternaire et ses conséquences sur vos requêtes
La logique ternaire impacte bien plus que les simples clauses WHERE. Elle se propage dans les jointures, les agrégats et les expressions conditionnelles. Comprendre ses effets vous évitera des heures de débogage.
NULL dans les agrégats
Les fonctions d'agrégat comme SUM, AVG, COUNT ignorent silencieusement les valeurs NULL. COUNT(*) compte toutes les lignes, mais COUNT(colonne) exclut les lignes où colonne est NULL — une différence qui peut fausser vos métriques.
-- Compte toutes les lignes : 1000
SELECT COUNT(*) FROM commandes;
-- Compte uniquement les lignes avec un montant renseigné : 847
SELECT COUNT(montant) FROM commandes;
Pour approfondir les subtilités des fonctions d'agrégat, consultez notre guide sur les fonctions d'agrégat SQL : SUM, COUNT, AVG, MIN, MAX.
NULL dans les jointures
Un NULL dans une colonne de jointure ne correspond jamais à un autre NULL. Deux lignes dont la clé de jointure est NULL ne seront donc pas associées, même en LEFT JOIN. Ce comportement est souvent source de pertes de données silencieuses dans les pipelines ETL.
⚠️ Attention
Dans une condition de jointure, NULL n'est jamais égal à NULL. Si vos colonnes de clé contiennent des NULL, les lignes correspondantes seront perdues sans aucun message d'erreur. Nettoyez vos données en amont ou utilisez COALESCE pour substituer une valeur sentinelle.
NULL dans les expressions arithmétiques
Toute opération arithmétique impliquant NULL retourne NULL. 100 + NULL = NULL, NULL * 5 = NULL. Si votre calcul de revenu utilise une colonne partiellement renseignée, le résultat sera NULL pour toutes les lignes concernées.
Les outils SQL pour traiter les NULL
SQL propose plusieurs fonctions natives pour gérer les valeurs manquantes de façon propre et lisible.
COALESCE : remplacer NULL par une valeur par défaut
COALESCE(expr1, expr2, ..., exprN) retourne la première valeur non-NULL de la liste. C'est la fonction la plus utilisée pour sécuriser les calculs.
-- Remplace un montant NULL par 0 avant de calculer
SELECT
id_commande,
COALESCE(montant, 0) AS montant_securise
FROM commandes;
Vous pouvez enchaîner plusieurs alternatives : COALESCE(prix_promo, prix_standard, 0) cherche d'abord un prix promotionnel, puis le prix standard, puis retourne 0.
NULLIF : produire NULL sous condition
NULLIF(expr1, expr2) retourne NULL si les deux expressions sont égales, sinon retourne expr1. Son usage le plus courant : éviter les divisions par zéro.
-- Évite la division par zéro
SELECT
chiffre_affaires / NULLIF(nombre_transactions, 0) AS panier_moyen
FROM stats_mensuelles;
Sans NULLIF, une division par zéro lèverait une erreur et interromprait votre requête.
CASE WHEN pour une logique conditionnelle avancée
Quand la logique de remplacement est complexe, CASE WHEN offre plus de flexibilité que COALESCE. Vous pouvez combiner les deux pour des traitements élaborés.
SELECT
utilisateur_id,
CASE
WHEN statut IS NULL THEN 'Non défini'
WHEN statut = '' THEN 'Vide'
ELSE statut
END AS statut_propre
FROM utilisateurs;
Pour aller plus loin sur les expressions conditionnelles, lisez notre article sur CASE WHEN en SQL : syntaxe, exemples et cas pratiques.
Tableau comparatif des fonctions de gestion des NULL
| Fonction | Syntaxe | Cas d'usage principal | Compatibilité |
|---|---|---|---|
| IS NULL | colonne IS NULL |
Filtrer les lignes sans valeur | Tous les SGBD |
| COALESCE | COALESCE(val1, val2, ...) |
Remplacer NULL par une valeur par défaut | Tous les SGBD |
| NULLIF | NULLIF(expr1, expr2) |
Produire NULL pour éviter erreurs (ex. div/0) | Tous les SGBD |
| IFNULL | IFNULL(val, defaut) |
Équivalent COALESCE à 2 arguments | MySQL, SQLite |
| NVL | NVL(val, defaut) |
Équivalent COALESCE à 2 arguments | Oracle uniquement |
| ISNULL | ISNULL(val, defaut) |
Équivalent COALESCE à 2 arguments | SQL Server uniquement |
💡 Bon à savoir
Privilégiez toujours COALESCE plutôt que IFNULL, NVL ou ISNULL : c'est la seule fonction standard ISO SQL, elle fonctionne sur tous les moteurs et accepte plus de 2 arguments. Votre code sera portable sans modification.
NULL et les contraintes de table
La gestion des NULL commence au niveau de la définition des tables. La contrainte NOT NULL interdit toute insertion de valeur manquante sur une colonne — c'est votre première ligne de défense contre la propagation de NULL dans vos données.
CREATE TABLE clients (
id INT NOT NULL PRIMARY KEY,
nom VARCHAR(100) NOT NULL,
email VARCHAR(200) NOT NULL,
telephone VARCHAR(20) NULL -- explicitement facultatif
);
Documenter explicitement quelles colonnes acceptent NULL avec le mot-clé NULL (même quand c'est le défaut) améliore la lisibilité du schéma et communique l'intention aux autres développeurs.
Une bonne pratique consiste à définir une valeur par défaut avec DEFAULT pour les colonnes numériques et booléennes fréquemment agrégées, afin d'éviter les surprises dans vos calculs downstream.
NULL dans les entretiens techniques : ce qu'on vous demandera
Les questions sur NULL apparaissent régulièrement dans les tests techniques data analyst. Voici les 3 scénarios les plus fréquents :
- Trouver les lignes sans correspondance : utiliser
LEFT JOINcombiné àWHERE table_droite.id IS NULLpour identifier les enregistrements orphelins - Compter les valeurs manquantes :
COUNT(*) - COUNT(colonne)donne le nombre de NULL dans une colonne - Calculer un ratio sans erreur :
COALESCEouNULLIFpour sécuriser les divisions et les agrégats
-- Compter les valeurs manquantes dans chaque colonne
SELECT
COUNT(*) - COUNT(nom) AS null_nom,
COUNT(*) - COUNT(email) AS null_email,
COUNT(*) - COUNT(telephone) AS null_telephone
FROM clients;
Ce type de requête d'audit de qualité est souvent demandé lors des cas pratiques en entretien. Entraînez-vous à l'écrire de mémoire.
Questions fréquentes
Quelle est la différence entre NULL et une chaîne vide en SQL ?
NULL signifie que la valeur est inconnue ou absente. Une chaîne vide '' est une valeur connue : une chaîne de longueur zéro. Les deux occupent de l'espace différemment, se comportent différemment dans les comparaisons et les agrégats. LENGTH(NULL) retourne NULL, LENGTH('') retourne 0.
Pourquoi WHERE colonne != 'valeur' n'inclut pas les lignes NULL ?
Parce que NULL != 'valeur' retourne UNKNOWN, pas TRUE. La clause WHERE n'inclut que les lignes où la condition est TRUE. Pour inclure les NULL, écrivez : WHERE colonne != 'valeur' OR colonne IS NULL.
COALESCE évalue-t-il tous ses arguments ?
Non, SQL utilise une évaluation court-circuit : COALESCE s'arrête dès qu'il trouve une valeur non-NULL. Cela peut avoir de l'importance si les arguments sont des sous-requêtes coûteuses — positionnez en premier les expressions les moins coûteuses et les plus souvent non-NULL.
Comment trier des lignes avec NULL en dernier ?
Par défaut, certains moteurs (PostgreSQL, Oracle) placent les NULL en premier en ordre descendant. Utilisez ORDER BY colonne NULLS LAST pour les forcer en fin de résultat. Sur MySQL, les NULL apparaissent en premier avec ASC — contournez avec ORDER BY colonne IS NULL, colonne.
NULL peut-il apparaître dans une colonne PRIMARY KEY ?
Non. Une clé primaire implique NOT NULL et UNIQUE. Aucun moteur SQL conforme au standard n'autorise NULL dans une colonne définie comme PRIMARY KEY.
Conclusion
NULL est un concept fondamental que tout praticien SQL doit maîtriser. En retenant que NULL signifie "valeur inconnue", que les comparaisons directes ne fonctionnent pas et que COALESCE est votre outil principal de substitution, vous éviterez les erreurs silencieuses les plus coûteuses.
En entretien comme en production, la capacité à diagnostiquer et à traiter les valeurs manquantes distingue un profil junior d'un profil confirmé. Mettez ces techniques en pratique dès aujourd'hui sur des jeux de données réels.
Prêt à tester vos connaissances face à un recruteur ? Découvrez notre simulateur d'entretien SQL pour vous exercer sur des cas concrets avec correction détaillée.
