Accueil Recherche | Plan Technique | Liens | Actualités | Formation | Emploi | Forums | Base
TUTORIEL cerig.efpg.inpg.fr 
Vous êtes ici : Accueil > Formation > Tutoriels > Bases de données relationnelles > La recherche d'information (début)
        Révision : 16 février 2003
 
                  Les bases de données
relationnelles
                 
Chap.
précéd.
Plan du
tutoriel
Liste des
tutoriels
Chap.
suivant
Chapitre 12 : la requête de sélection
1 - Introduction
                  Stocker sans cesse des informations dans une base de données, et en assurer la maintenance, n'est pas une fin en soi. Il faut pouvoir retrouver, chaque fois que cela est nécessaire, les informations pertinentes dont on a besoin. La requête de sélection a été créée dans ce but. Elle joue, dans les BDD, un rôle très important.          
Comme pour le reste de ce tutoriel (encore appelé "cours en ligne" ou tutorial), nous utiliserons le SGBD Access comme support pratique.
2 - La requête de sélection
                  Dans le cas le plus simple, la requête sélection s'applique à une seule table dont elle conserve toutes les colonnes. Contrairement à la sélection simple (ou projection) qui permet d'extraire d'une table certaines colonnes nommément désignées, la sélection permet d'extraire d'une table les lignes répondant à certains critères, comme le montre la figure ci-dessous. L'ensemble des critères d'une requête de sélection est parfois appelé filtre (par analogie avec le filtre manuel), et l'expression filtrer une table à l'aide d'une requête est assez courante.          
U V W X Y Z T
 1                                      
 2            
 3
 4            
 5            
 6
   
U V W X Y Z T
 2                                      
 4            
 5            
La sélection représente l'outil courant de recherche de l'information dans les bases de données. D'une manière générale, la sélection :
            s'applique soit à une seule table, soit à plusieurs tables liées par des relations ;
  permet de sélectionner les lignes par application d'un ou plusieurs critères portant sur un ou plusieurs champs ;
  permet de choisir les colonnes que l'on veut conserver (comme la sélection simple) ;
  peut enregistrer son résultat sous forme d'une table ;
  peut créer une nouvelle colonne ;
  peut être paramétrée.
Tout ce que nous avons exposé au chapitre 11 sur la sélection simple s'applique a fortiori à la sélection en général : choix des colonnes, requête multi table, création de table, création de champ, tri, requêtes emboîtées.
La formulation d'une requête de sélection met en jeu des critères liés par des opérateurs logiques. Sa réalisation pratique pose des problèmes de syntaxe, qui sont propres au SGBD utilisé. A titre d'exemple, recherchons les clients du représentant Dupont, ou de son collègue Durand, qui ont passé une commande de plus de 1.000 € le mois dernier. Dans une des tables de notre BDD se trouve une colonne "Représentant", et il faut que nous exprimions le fait que nous recherchons les enregistrements qui possèdent le nom Durand, ce qui soulève un problème de syntaxe (le nom "Durand" doit être mis entre guillemets). Ensuite, il faut que nous exprimions le fait que c'est "Durand" OU "Dupont", ce qui met en jeu l'opérateur logique OU. Dans une table nommée "Commandes" existe un champ "Coût total", et il faut que nous exprimions le fait que ce coût est supérieur à 1.000 €, ce qui met en jeu l'opérateur de comparaison "supérieur à".

3 - La syntaxe
                  La syntaxe varie avec le type de données du champ sur lequel porte le critère :          
            une donnée de type texte doit être écrite entre guillemets ("..."), et précédée de l'opérateur "Comme". Cet opérateur peut être omis si aucun opérateur de comparaison n'est présent ;
  les nombres sont écrits tels quels ;
  la date et / ou l'heure doivent être placées entre dièses (exemple : #01/01/2003#). Dans certains SGBD, le dièse est remplacé par l'apostrophe ;
  un booléen doit être déclaré vrai ou faux.
La valeur Null (case vide, pas de données) possède une syntaxe particulière. Pour détecter les enregistrements dont un champ particulier est vide, il faut écrire :
Est Null
Dans le cas contraire, il faut écrire :
Est Pas Null
La casse n'a pas d'importance, le SGBD corrigeant de lui-même.
4 - Les caractères génériques
                  Pour exprimer le fait que nous recherchons les enregistrements qui possèdent la chaîne de caractères "truc" dans un champ donné, nous écrivons, conformément aux indications du paragraphe précédent :          
Comme "truc"
L'application d'un critère à un champ de type texte recèle un piège particulier. Quand nous exprimons ce critère comme ci-dessus, nous ne sélectionnons que les enregistrements possédant exactement la chaîne "truc" dans le champ considéré. Si le champ contient "trucage", ou "le truc", l'enregistrement correspondant est ignoré.
Il nous faut donc pouvoir préciser comment la chaîne recherchée se présente dans le champ : occupe-t-elle tout le champ, est-elle précédée ou suivie d'autres caractères, et (éventuellement) quel est leur nombre. Pour ce faire, nous utilisons des caractères génériques, c'est à dire des caractères qui peuvent remplacer un ou plusieurs autres caractères quels qu'ils soient. Le caractère générique le plus fréquemment utilisé est l'astérisque, qui remplace un nombre quelconque de caractères. Ainsi :
Comme "*truc"
permet de sélectionner tout enregistrement dont le champ considéré contient une chaîne de caractères se terminant par "truc", telle que "truc" et "le truc" par exemple. Par contre, "trucage" sera ignoré. De même :
Comme "truc*"
permet de sélectionner tout enregistrement dont le champ considéré contient une chaîne de caractères commençant par "truc", telle que "truc" et "trucage". Par contre, "le truc" sera ignoré. Enfin :
Comme "*truc*"
permet de sélectionner tout enregistrement dont le champ considéré contient la chaîne "truc", tel que "truc", "trucage" et "le truc".
L'astérisque peut être placée n'importe où, et non pas seulement en début ou en fin de chaîne. Ainsi, une requête exprimée ainsi :
Comme "/tutoriel/*htm"
retrouvera, dans le journal du serveur du CERIG, toutes les pages HTML dédiées au présent tutoriel. Il n'est pas nécessaire de placer une astérisque en début de chaîne parce que, dans le fichier journal, le serveur web ne reproduit pas le début de l'adresse (http://cerig.efpg.inpg.fr).
Le second caractère générique (par fréquence d'usage) est le point d'interrogation, qui remplace un caractère quelconque et un seul. Ainsi, le critère :
Comme "c?d"
retrouvera par exemple cad, ced, cid, cod, mais pas cd car le point d'interrogation implique la présence d'un caractère.
Si l'on veut rechercher l'astérisque ou le point d'interrogation dans un champ, il faut placer ces caractères entre crochets. Par exemple, la recherche du point d'interrogation (placé n'importe où dans un champ) s'écrit :
Comme "*[?]*"
Attention ! Les caractères génériques * et ? ne s'appliquent qu'à l'interrogation des champs de type texte. Dans un champ de type Date/Heure, une expression telle que #**/**/2002# est considérée comme invalide par le SGBD Access. Notons de plus que, dans les versions récentes de la plupart des SGBD, l'astérisque est remplacée par le pourcent (%) et le point d'interrogation par le caractère de soulignement (_). Une annexe traitera de l'usage des caractères génériques plus en détail.
5 - Les opérateurs logiques
                  Une requête un peu élaborée fait appel à plusieurs critères s'appliquant soit à un même champ, soit à des champs distincts. Ces critères sont liés par des opérateurs logiques, dont les plus utilisés sont ET, OU et PAS. L'utilisation de parenthèses permet de définir l'ordre dans lequel s'appliquent les opérateurs. Les personnes familiarisées avec la recherche documentaire connaissent bien cette façon de procéder, qui provient directement de la théorie des ensembles.          
Dans Access, les opérateurs logiques Et et OU peuvent être écrits explicitement, ou être représentés graphiquement dans la grille de l'interface graphique de création d'une requête. L'opérateur PAS doit être écrit explicitement.
Pour rechercher, dans le champ "Nom" d'une table intitulée "Personnes", les individus s'appelant Truc ou Machin, nous avons le choix entre les deux solutions que nous avons représentées ci-dessous (en détourant une partie de la grille de définition de la requête) :
Opérateur OU graphique    Opérateur OU explicite
Nous voyons que l'opérateur OU peut être écrit explicitement (à droite), ou traduit graphiquement (à gauche). Le résultat de la requête est, bien entendu, le même dans les deux cas.
L'opérateur logique peut porter sur deux champs distincts. La traduction graphique de l'opérateur OU est alors plus simple que son écriture explicite, comme le montrent les figures ci-dessous. On notera que le OU s'obtient en se décalant d'une ligne... sinon c'est l'opérateur ET qui fonctionne !
Opérateur OU sur 2 champs (graphique)
 
Opérateur OU sur 2 champs (explicite)
L'opérateur ET peut lui aussi être traduit graphiquement ou écrit explicitement, comme le montrent les figures ci-dessous. La requête recherche les noms commençant par la lettre "m" et finissant par la lettre "n", et retrouve par exemple "Machin".
Opérateur ET (explicite)    Opérateur ET graphique
Notons que la requête aurait pu être formulée plus simplement : Comme "m*n".
L'opérateur logique peut impliquer deux champs distincts, comme le montre l'exemple ci-dessous. La requête recherche les enregistrements relatifs à une personne nommée Pierre Machin.
Opérateur ET sur 2 champs (graphique)
 
Opérateur ET sur 2 champs (explicite)
Conclusion : dans la grille de création d'une requête, le déplacement horizontal correspond à l'opérateur ET, et le déplacement vertical correspond à l'opérateur OU. L'opérateur PAS est sans représentation graphique.
Dans une requête complexe, l'application des opérateurs s'effectue ligne par ligne, comme le montre l'exemple ci-dessous.
Une requête s'effectue ligne par ligne
La requête fonctionne selon l'expression ensembliste suivante :
((Personnes.Nom Comme "machin") ET (Personnes.Prénom Comme "pierre"))
OU
((Personnes.Prénom Comme "jacques") ET (Personnes.[Date naissance]=#8/30/1975#))
c'est à dire que :
            l'expression qui se trouve sur la ligne "Critères :" est évaluée (elle réalise un ET) ;
  l'expression qui se trouve sur la ligne "Ou :" est évaluée (elle réalise aussi un ET) ;
  un OU est ensuite effectué entre les résultats des deux expressions précédentes.
6 - Les opérateurs de comparaison
                  Les opérateurs de comparaison arithmétiques :          
= (égal), < (inférieur), <= (inférieur ou égal), > (supérieur), >= (supérieur ou égal), <> (différent)
s'appliquent aux données numériques et monétaires, mais aussi aux dates et aux chaînes de caractères. Pour ces dernières, on notera que :
            le signe égal est équivalent à l'opérateur "Comme" ;
  le signe différent est équivalent à l'opérateur "Pas Comme".
Pour préciser un intervalle, on peut utiliser l'expression :
Entre ... Et ...
qui fonctionne avec les types de données texte, date/heure et numérique/monétaire.
7 - Les fonctions
                  Pour exprimer des critères, on peut utiliser des fonctions, mais ces dernières sont spécifiques à la fois du SGBD et du type de données du champ considéré. Nous consacrerons une annexe aux fonctions, et nous nous contenterons ici de citer quelques exemples (dont nous avons vérifié qu'ils fonctionnaient effectivement).          
Pour les champs en mode texte :
            NbCar([Nom])="4" retrouve les noms de 4 caractères ;
  Droite([Nom];2)="se" retrouve les noms se terminant par "se" ;
  Gauche([Nom];2)="du" retrouve les noms commençant par "du" ;
  ExtracChaîne([Nom];2;3)="ach" retrouve le nom "Machin", lequel contient la chaîne de 3 caractères "ach" en commençant au deuxième caractère.
Pour les dates et les heures :
            PartDate("aaaa";[Date_commande])=2000 retrouve les commandes de l'année 2000. Cette fonction opère aussi avec "j" pour le jour, "m" pour le mois, et "t" pour le trimestre ;
  DiffDate("j";[Date_commande];[Date_livraison])>100 retrouve les produits qui ont été livrés plus de 100 jours après avoir été commandés. Cette fonction opère aussi avec "m" pour le mois, et avec "aaaa" pour l'année ;
  Jour([Date_commande])=12 retrouve les commandes effectuées le 12 (des mois présents dans la table) ;
  Mois([Date_commande])=6 retrouve les commandes du mois de juin ;
  Année([Date_commande])=2000 retrouve les commandes de l'année 2000 ;
  AjDate("j";-10;[Date_livraison]) fournit une date antérieure de 10 jours à la date de livraison.
Attention ! La francisation des fonctions (date/heure) issues de VBA n'a pas toujours été effectuée par l'éditeur avec tout le sérieux nécessaire, et l'utilisateur ne doit pas être surpris s'il se heurte à des disfonctionnements. Ainsi la fonction :
JourSem(#date#)
qui donne le numéro du jour d'une date donnée, marche à l'américaine : le jour numéro 1 est le dimanche, et non le lundi comme c'est le cas en Europe. Par contre, la fonction :
WeekdayName(n° du jour)
qui donne le nom du jour connaissant son numéro, fonctionne à l'européenne : le jour n° 1 est bien le lundi. Il en résulte que l'expression obtenue en emboîtant les deux fonctions précédentes :
WeekdayName(JourSem(#date#))
donne un résultat faux (le lundi à la place du dimanche, etc.). De même les fonctions qui, dans leurs arguments, acceptent le jour ("j"), le mois ("m"), le trimestre ("t") et l'année ("aaaa"), n'acceptent pas la semaine contrairement à ce qui se passe dans la version anglophone d'Access.
Pour les champs de type numérique ou monétaire, on trouve :
            les fonctions arithmétiques habituelles (somme, différence, produit, quotient) ;
  des fonctions mathématiques et statistiques ;
  des fonctions telles que Abs() (valeur absolue), Arrond() (partie entière), Ent() (partie entière, arrondie inférieurement pour les nombres négatifs), Aléat() (nombre aléatoire compris entre 0 et 1) et Sgn() (signe d'un nombre).
A la valeur particulière Null correspond la fonction :
EstNull([Nom d'un champ])
Elle retourne la valeur -1 si le champ est vide, et 0 (zéro) dans le cas contraire.
Attention ! Notez bien que, lorsqu'une fonction possède plusieurs arguments, le caractère séparateur est le point-virgule, alors que c'est la virgule dans la version anglophone d'Access. C'est un détail de syntaxe ridicule, mais il est à l'origine de bien des mauvaises surprises.
8 - La requête de sélection paramétrée
                  Soit une table contenant diverses informations, dont une date, comme le montre l'exemple ci-dessous.          
Imaginons que nous ayons régulièrement besoin des informations relatives à un jour donné. Nous pouvons, bien sûr, créer chaque fois une requête nouvelle, mais il est plus commode d'écrire une seule fois la requête et de paramétrer la valeur de la date. Dans la grille de création de la requête, la valeur du paramètre date est remplacée par un message écrit entre crochets :
Requête paramétrée sur une date
Si nous lançons la requête, la boite de dialogue suivante s'affiche :
Boite de dialogue
Nous saisissons la date dans le format utilisé par la table (jj/mm/aaaa), et nous validons. Le SGBD affiche les lignes relatives à la date indiquée :
Données sélectionnées
9 - Conclusion
                  Les SGBD mettent à la disposition des utilisateurs des outils extrêmement variés pour exprimer les critères utilisés dans l'élaboration d'une requête. En emboîtant, si nécessaire, plusieurs requêtes, les utilisateurs peuvent extraire des BDD toutes les informations qu'ils désirent -- ou presque. Il est fort rare que l'on se trouve dans l'impossibilité réelle de transcrire un critère donné.          
    Pour qui fait l'effort d'apprendre à créer des requêtes, et obtient de son entreprise l'autorisation de s'en servir, il y a là une mine d'or... au sens de l'information tout au moins.  
Chapitre précédent Plan du tutoriel Liste des tutoriels Chapitre suivant
Accueil | Technique | Liens | Actualités | Formation | Emploi | Forums | Base
Copyright © CERIG/EFPG 1996-2003
Réalisation et mise en page : J.C. Sohm

Remarque : le résultat d'une requête écrite en SQL peut servir de critère pour une requête définie dans l'interface graphique. Ce point sera traité ultérieurement.