L'opérateur IN

L'opérateur SQL IN : Comment utiliser une liste d'éléments dans une requête

Fabrice Constans

L'opérateur IN, à la différence de LIKE, n'est disponible que pour SQL. Au vu de l'interaction de ce langage avec ACCESS, il peut vous rendre de précieux services et vous éviter des expressions à rallonge.

Commentez cet article : Commentez
♪

- Titre : L'opérateur IN

- Auteur : Fabrice Constans

- Parution : 30 juillet 2011

- Mise à jour : 3 octobre 2011

- Licence : Copyright ® 2011 Fabrice CONSTANS. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- 0. Introduction

- I. La syntaxe

- I-A. IN vs. =

- II. En pratique

- II-A. Zone liste, IN et état

- II-A-1. Variante avec du texte

- II-A-2. Variante avec des dates

- III. Limitation

- IV. Conclusion

- V. Remerciement

0 - Introduction

L'opérateur logique IN est un opérateur d'égalité strictement réservé à SQL. Il permet de déterminer si la valeur d'une expression est égale à l'une des valeurs comprises dans une liste donnée.

L'opérateur IN ne doit être confondu ni avec la clause de SQL qui détermine une source de données ni avec le mot clef VBA de la syntaxe For.

I - La syntaxe

La syntaxe est la suivante :

WHERE NomChamp IN (valeur1, valeur2, ... , valeurX )

La liste d'éléments à comparer est placée entre parenthèses.

On peut également trouver sa forme négative :

WHERE NomChamp NOT IN (valeur1, valeur2, ... , valeurX )

Il faut savoir que dans sa forme négative, il ne bénéficie pas de l'optimisation Rushmore. Pour en savoir plus sur la technologie Rushmore consultez le tutoriel sur l'optimisation des bases de données Microsoft Access.

https://loufab.developpez.com/tutoriels/access/optimisation/

On peut également utiliser une requête comme liste d'éléments à comparer, à condition que cette dernière ne renvoie qu'un champ.

SELECT * FROM TableA WHERE NomChamp IN (SELECT ChampId FROM TableB)

Cette forme de relation est intéressante par la souplesse de sa rédaction.

I-A - IN vs. =

Les exemples suivants démontrent l'avantage de l'opérateur IN.

Avec l'opérateur d'égalité la requête aura cette forme :

SELECT * FROM TableA WHERE champId = 1 or champId = 3 or champId = 10;

La même requête simplifiée grâce à l'opérateur IN :

SELECT * FROM TableA WHERE champId IN (1,3,10);

II - En pratique

Nous allons voir comment l'opérateur s'intègre parfaitement au fonctionnement d'une application pour créer des filtres à moindre coût.

II-A - Zone liste, IN et état

La zone de liste est un contrôle sympathique, encore faut-il pouvoir tirer parti de sa sélection multiple.

Pour la mise en pratique vous avez besoin d'une table contenant au moins un identifiant unique de type numérique et un champ de type texte.

Commencez par créer un formulaire composé d'une zone de liste et d'un bouton de commande.

La zone de liste doit être réglée de la manière suivante :

Nom

Zliste

Nbre Colonnes

2

Largeurs colonnes

0 ;5

Contenu

SELECT TCategorie.IdCategorie, TCategorie.Nom FROM TCategorie ORDER BY TCategorie.Nom;

Sélection Multiple

Simple (ou Étendue)

Voici le résultat.

Créez ensuite un état nommé Test contenant les champs de cette même table. Peu importe la mise en page, c'est pour l'exemple.

Grâce à l'opérateur IN nous allons imprimer les éléments choisis dans la liste.

Dans l'événement Sur clic du bouton de commande insérez le code suivant :

Private Sub Commande2_Click()
Dim itm As Variant          ' l'item choisi
Dim lstval As String        ' la liste des id sélectionnés
For Each itm In Me.Zliste.ItemsSelected                 ' parcourt les items
lstval = lstval & Me.Zliste.ItemData(itm) & ","     ' insère chaque id dans la variable
Next
lstval = Left(lstval, Len(lstval) - 1)                  ' supprime la dernière virgule
DoCmd.OpenReport "Test", acViewPreview, , "IdCategorie IN (" & lstval & ")"  ' imprime la sélection
End Sub

La méthode est simple, cependant elle ne gère pas l'erreur levée lorsqu'il n'y a pas de choix.

Sélectionnez quelques éléments et cliquez sur le bouton.

II-A-1 - Variante avec du texte

La syntaxe est pratiquement identique à une différence près. Comme nous utilisons des éléments texte il faut utiliser le séparateur texte dans la liste de l'opérateur IN.

Changez la propriété de la liste :

Colonne Liée

2

Modifiez le code du bouton :

lstval = lstval & """" & Me.Zliste.ItemData(itm) & ""","   ' insère chaque id dans la variable

Modifiez l'appel de l'état pour intégrer le nouveau nom de champ.

DoCmd.OpenReport "Test", acViewPreview, , "Nom IN (" & lstval & ")"  ' imprime la sélection

La syntaxe SQL sera donc :

WHERE NOM IN ("coiffeur","concerts" )

II-A-2 - Variante avec des dates

Construisez un nouvel état avec cette source contenant une date et un champ texte. Indiquez la même source pour la zone de liste.

La ligne de construction de la liste change. Il faut mettre le symbole dièse (#) qui est le séparateur de dates et le format de date US.

lstval = lstval & "#" & Format(Me.ZListe.ItemData(itm), "mm/dd/yyyy") & "#,"    ' insère chaque date

Les dates dans VBA doivent toujours être au format anglo-saxon.

L'appel du formulaire change également pour utiliser le bon nom de champ.

DoCmd.OpenReport "Test2", acViewPreview, , "DateOperation IN (" & lstval & ")"  ' imprime la sélection

La syntaxe SQL sera donc :

WHERE DateOperation IN (#10/02/2011#,#12/12/2010#)

III - Limitation

Hormis le problème avec la forme négative de l'opérateur IN (Not IN) les limitations ne sont pas légion. En effet la liste peut compter plusieurs centaines d'éléments.

La valeur NULL doit être considérée avec précaution. Comparée à un élément de la liste elle peut produire des effets inattendus.

La liste est un ensemble de 1 à x éléments. On peut donc utiliser ce code quel que soit le nombre de sélections.

IV - Conclusion

Utiliser l'opérateur IN simplifie grandement la construction des requêtes SQL. Il évite de longs et complexes algorithmes de construction de clause WHERE ou HAVING et facilite l'écriture des requêtes de vérifications de clefs externes.

V - Remerciement

Je remercie Claude LELOUP pour ses corrections, ainsi que f_leb et philben pour leurs remarques.