La condition SQL WHERE filtre les lignes d’une table et conserve uniquement les enregistrements qui satisfont la condition définie dans la requête.
Table des matières
Syntaxe de base
La clause WHERE se place toujours après FROM et avant GROUP BY ou ORDER BY dans une requête SQL. Elle s’utilise avec SELECT, UPDATE et DELETE pour cibler précisément les lignes concernées. Le moteur SQL exécute FROM en premier pour charger la table, puis applique immédiatement WHERE pour réduire l’ensemble de données traité.
SELECT nom, prix
FROM produits
WHERE prix < 100;
La condition prix < 100 conserve uniquement les lignes dont la colonne prix est inférieure à 100. Vérifiez que le type de la colonne correspond bien à la valeur comparée pour éviter une conversion implicite silencieuse.
Comparer des valeurs avec les opérateurs de base
Les opérateurs de comparaison =, >, <, >=, <= et <> forment la base du filtrage dans la condition. Ils fonctionnent avec les nombres et les chaînes de caractères, ces dernières devant toujours être encadrées par des guillemets simples. L’opérateur AND exige que toutes les conditions soient vraies simultanément pour qu’une ligne soit retournée.
La requête suivante sélectionne les clients âgés de plus de 25 ans qui habitent Paris.
SELECT nom
FROM clients
WHERE age > 25 AND ville = 'Paris';
Seules les lignes satisfaisant les deux conditions sont retournées dans le résultat. Un client de 30 ans habitant Lyon est exclu car la condition sur ville n’est pas remplie.
Filtrer une plage de valeurs avec BETWEEN
BETWEEN teste si une valeur est comprise entre deux bornes inclusives définies dans la condition. Il équivaut à une double comparaison avec AND et s’applique aux nombres, aux dates et aux chaînes de caractères. Cette syntaxe est plus lisible qu’une condition avec deux opérateurs >= et <= séparés.
La requête suivante sélectionne les produits dont la quantité en stock est comprise entre 10 et 50 unités.
SELECT produit
FROM stock
WHERE quantite BETWEEN 10 AND 50;
Les bornes 10 et 50 sont incluses dans le résultat. Un produit avec une quantité de 9 ou de 51 est exclu du résultat retourné.
Rechercher un motif avec LIKE
LIKE recherche un motif dans une chaîne de caractères grâce aux caractères spéciaux % et _. Le caractère % représente zéro ou plusieurs caractères, tandis que _ représente exactement un caractère. La distinction entre majuscules et minuscules dépend du SGBD et du paramétrage de la base de données.
La requête suivante retourne tous les clients dont le nom commence par la chaîne Du.
SELECT nom
FROM clients
WHERE nom LIKE 'Du%';
Le résultat inclut Dupont, Durand ou Dubois car tous commencent par Du. Évitez de placer % en début de motif comme '%moteur%', car cette forme empêche l’utilisation des index et ralentit les requêtes sur les grandes tables.
Tester une liste de valeurs avec IN
IN vérifie si une valeur appartient à une liste prédéfinie et remplace avantageusement plusieurs conditions OR successives. Cette syntaxe est plus lisible et plus concise que d’enchaîner trois ou quatre comparaisons avec =. IN fonctionne également avec des sous-requêtes pour des listes dynamiques.
La requête suivante sélectionne les commandes dont le statut appartient à la liste des valeurs actives.
SELECT nom
FROM commandes
WHERE statut IN ('en_cours', 'expedie', 'livre');
Cette condition équivaut à trois comparaisons séparées par OR mais s’écrit en une seule ligne. Vérifiez que chaque valeur de la liste est bien encadrée par des guillemets simples pour les colonnes de type texte.
Détecter les valeurs manquantes avec IS NULL
IS NULL détecte les cellules vides dans une table, car l’opérateur = ne fonctionne jamais avec NULL. NULL signifie « valeur inconnue » et non « valeur égale à zéro ». IS NOT NULL sélectionne à l’inverse les lignes dont la colonne contient une valeur renseignée.
La requête suivante identifie les clients qui n’ont pas renseigné leur adresse email dans la base.
SELECT nom
FROM clients
WHERE email IS NULL;
Toutes les lignes dont la colonne email est vide apparaissent dans le résultat. Utilisez IS NOT NULL pour sélectionner uniquement les clients dont l’email est renseigné.
Gérer la priorité des opérateurs logiques
AND s’évalue toujours avant OR dans une condition, ce qui peut produire des résultats inattendus sans parenthèses. Les parenthèses modifient cet ordre de priorité et rendent l’intention du développeur explicite. NOT s’applique en priorité à la condition placée entre parenthèses, avant tout autre opérateur.
La requête suivante illustre la différence entre une condition ambiguë et une condition correctement parenthésée.
-- Ambigu : AND s'évalue avant OR
SELECT nom FROM clients
WHERE age > 18 OR ville = 'Paris' AND statut = 'actif';
-- Équivaut à : (age > 18) OR (ville = 'Paris' AND statut = 'actif')
-- Explicite : les parenthèses définissent l'ordre voulu
SELECT nom FROM clients
WHERE (age > 18 OR ville = 'Paris') AND statut = 'actif';
La version sans parenthèses retourne tous les clients de plus de 18 ans, quelle que soit leur ville. La version parenthésée n’inclut que les actifs parmi les clients de plus de 18 ans ou habitant Paris.
Utiliser une condition avec UPDATE et DELETE
WHERE protège les requêtes UPDATE et DELETE contre les modifications ou suppressions massives accidentelles. Sans cette clause, l’action s’applique à toutes les lignes de la table sans exception. Ces deux commandes exigent systématiquement une condition en environnement de production.
Les deux requêtes suivantes illustrent l’usage de WHERE pour limiter l’impact d’un UPDATE et d’un DELETE.
-- Augmenter uniquement les produits de la catégorie luxe
UPDATE produits
SET prix = prix * 1.2
WHERE categorie = 'luxe';
-- Supprimer uniquement les logs antérieurs à 2026
DELETE FROM logs
WHERE date_creation < '2026-01-01';
Sans condition, UPDATE produits SET prix = prix * 1.2 modifie le prix de tous les produits de la table. Testez toujours la condition avec un SELECT identique avant d’exécuter le UPDATE ou le DELETE.
Bonnes pratiques
Règle 1 — Indexer les colonnes utilisées dans WHERECREATE INDEX idx_ville ON clients(ville) accélère le filtrage sur ville pour les opérateurs =, >, < et BETWEEN.
Règle 2 — Éviter les fonctions sur les colonnes filtréesWHERE date_creation >= '2025-01-01' utilise l’index, contrairement à WHERE YEAR(date_creation) = 2025 qui force un parcours complet de la table.
Règle 3 — Tester avec LIMIT en développementSELECT * FROM produits WHERE prix < 100 LIMIT 10 valide le filtrage sur un échantillon réduit avant d’exécuter la requête complète.
Règle 4 — Utiliser EXPLAIN pour analyser les performancesEXPLAIN SELECT * FROM produits WHERE prix < 100 révèle si le moteur utilise un index ou effectue un parcours complet de la table.
Règle 5 — Parenthéser les conditions complexesWHERE (age > 18 OR ville = 'Paris') AND statut = 'actif' rend l’ordre d’évaluation explicite et évite les résultats inattendus liés à la priorité de AND sur OR.
Cas pratique métier
Un service marketing extrait les clients parisiens actifs dont le solde dépasse 1 000 € pour une campagne de fidélisation trimestrielle.
SELECT nom, email, solde
FROM clients
WHERE ville = 'Paris'
AND statut = 'actif'
AND solde > 1000
ORDER BY solde DESC;
Erreurs courantes
❌ Erreur : comparaison avec NULL via l'opérateur =
SELECT * FROM clients WHERE email = NULL;
-- NULL ne se compare jamais avec = , le résultat est toujours vide.
✅ Correct :
SELECT * FROM clients WHERE email IS NULL;
❌ Erreur : % en début de motif LIKE
SELECT * FROM produits WHERE description LIKE '%moteur%';
-- Le % initial empêche l'utilisation de l'index sur la colonne description.
✅ Correct :
SELECT * FROM produits WHERE description LIKE 'moteur%';
❌ Erreur : UPDATE sans WHERE
UPDATE produits SET prix = 0;
-- Tous les prix de la table sont mis à zéro sans exception.
✅ Correct :
UPDATE produits SET prix = 0 WHERE en_promo = 1;
Sources : MySql , Postgresql