SQL IN : filtrage de lignes par liste
L’opérateur SQL IN teste si une valeur correspond à un élément d’une liste. Un prédicat SQL WHERE IN remplace de longues chaînes OR lors d’un filtrage par un ensemble connu de valeurs discrètes : codes de statut, noms de catégorie, identifiants de région. Utilisez une liste SQL WHERE IN quand les valeurs sont connues à l’avance et que la condition doit rester lisible à mesure qu’elle s’allonge.
Exemple SQL IN pour correspondance dans une liste
Sortie :
La sortie apparaîtra ici...
Sortie :
+---------+--------------+
| nom | categorie |
+---------+--------------+
| Carnet | papeterie |
| Clavier | électronique |
| Gomme | papeterie |
| Souris | électronique |
+---------+--------------+
4 row(s)
Comment cet exemple fonctionne
CREATE TABLEetINSERTremplissent une tableproduitsavec cinq lignes réparties dans trois catégories.WHERE categorie IN ('électronique', 'papeterie')sélectionne chaque ligne dontcategorieest égale à l’une des valeurs de la liste. Logiquement, c’est équivalent àcategorie = 'électronique' OR categorie = 'papeterie'.- La ligne
mobilierest exclue car sacategorien’est pas dans la liste. ORDER BY nomrend la sortie déterministe.
IN avec une liste littérale est équivalent à des comparaisons OR en chaîne, mais passe mieux à l’échelle quand l’ensemble grandit : ajouter une valeur signifie ajouter un élément dans la liste, pas une clause OR supplémentaire.
Qu’est-ce que l’opérateur SQL IN ?
L’opérateur SQL IN est une forme abrégée de plusieurs comparaisons d’égalité reliées par OR. WHERE x IN (a, b, c) est logiquement identique à WHERE x = a OR x = b OR x = c. Avec la logique ternaire de SQL, si aucun élément ne correspond et qu’aucun élément n’est NULL, IN renvoie faux. Si un élément est NULL et qu’aucune correspondance exacte n’existe, le résultat est inconnu ; dans une clause WHERE, inconnu filtre la ligne.
Gérer une liste SQL WHERE IN vide
La plupart des bases rejettent WHERE col IN () avec une erreur de syntaxe, ce qui apparaît souvent lors de la génération dynamique d’une liste SQL WHERE IN. Gérez explicitement le cas vide : ignorez le filtre, ou forcez un prédicat toujours faux comme WHERE 1 = 0 quand une liste vide doit renvoyer zéro ligne.
SQL NOT IN et le piège NULL
SQL NOT IN inverse le test : il renvoie vrai seulement quand la valeur est différente de chaque élément de la liste. Un seul NULL dans la liste peut faire basculer le résultat vers inconnu, car x <> NULL vaut toujours inconnu, et WHERE traite inconnu comme faux :
-- Renvoie 0 ligne : NULL rend le prédicat UNKNOWN
SELECT nom
FROM produits
WHERE categorie NOT IN ('électronique', NULL);
Quand la liste vient d’une sous-requête, filtrez les NULL dans la sous-requête, ou utilisez NOT EXISTS pour des sémantiques sûres avec NULL.
IN avec des sous-requêtes
IN accepte aussi une sous-requête à la place d’une liste littérale. Conceptuellement, la sous-requête produit un ensemble de valeurs, et la requête externe vérifie l’appartenance :
SELECT nom FROM produits
WHERE categorie IN (
SELECT categorie FROM produits WHERE nom LIKE '%et%'
);
Pour des sous-requêtes petites et non corrélées, cette forme fonctionne bien. Quand la sous-requête renvoie beaucoup de lignes ou implique une corrélation, un prédicat EXISTS ou un JOIN est souvent plus performant car l’optimiseur peut appliquer des stratégies de semi-join.
IN vs EXISTS vs JOIN
| Approche | Utilisez-la quand… |
|---|---|
IN (liste) | Filtrage par un petit ensemble connu de valeurs littérales |
IN (sous-requête) | Test d’appartenance sur un petit ensemble sans NULL |
EXISTS (sous-requête) | Vérification corrélée ou clés étrangères nullables |
JOIN | Vous avez besoin de colonnes des deux tables dans le résultat |
BETWEEN | Les valeurs forment une plage continue, pas des éléments discrets |
Règle : utilisez IN pour des ensembles de valeurs discrètes. Passez à EXISTS quand la sous-requête est corrélée ou nullable. Utilisez un JOIN quand vous avez besoin des données des deux côtés.
Notes de performance
IN sur une colonne indexée est sargable : l’optimiseur peut faire des recherches d’index pour chaque valeur de la liste. Certains moteurs trient les listes IN littérales en interne pour une évaluation par recherche binaire. De très grandes listes littérales (centaines de valeurs) peuvent ralentir l’analyse de la requête et la génération du plan ; chargez ces valeurs dans une table temporaire puis faites un JOIN.
FAQ
SQL IN est-il équivalent à plusieurs conditions OR ?
Oui, sur le plan logique. WHERE x IN (1, 2, 3) est équivalent à WHERE x = 1 OR x = 2 OR x = 3. L’optimiseur produit en général le même plan d’exécution pour les deux formes, mais IN est plus court et plus facile à maintenir quand la liste grandit.
Pourquoi NOT IN ne renvoie-t-il aucune ligne quand la sous-requête contient NULL ?
NOT IN se déploie en une chaîne de comparaisons AND : x <> a AND x <> b AND x <> NULL. Comme x <> NULL est toujours inconnu, l’expression complète n’est jamais vraie. Filtrez les NULL de la sous-requête ou utilisez NOT EXISTS pour éviter ce comportement.
Peut-on utiliser IN avec une sous-requête ?
Oui. WHERE col IN (SELECT col FROM other_table) vérifie l’appartenance au résultat de la sous-requête. Pour des ensembles petits et non nullables, c’est efficace. Pour des ensembles volumineux ou nullables, EXISTS ou un JOIN donne souvent plus de flexibilité à l’optimiseur.