|
Chapitre 11 :
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. |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|
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 : |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|
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 : |
|
||||||||||||
|
|
|
|
|
||||||||||||
|
|
|
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) : |
|
|||||||||
|
|
||||||||||||
|
|
|
|
|
|||||||||
|
|
||||||||||||
|
|
|
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 ! |
|
|||||||||
|
|
||||||||||||
|
|
||||||||||||
|
|
||||||||||||
|
|
|
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". |
|
|||||||||
|
|
||||||||||||
|
|
||||||||||||
|
|
||||||||||||
|
|
|
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. |
|
|||||||||
|
|
||||||||||||
|
|
||||||||||||
|
|
||||||||||||
|
|
|
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. |
|
|||||||||
|
|
||||||||||||
|
|
||||||||||||
|
|
||||||||||||
|
|
|
La
requête fonctionne selon l'expression ensembliste suivante : |
|
|||||||||
|
|
|
((Personnes.Nom Comme
"machin") ET (Personnes.Prénom Comme
"pierre")) |
|
|||||||||
|
|
|
c'est
à dire que : |
|
|||||||||
|
|
|
|
|
|||||||||
|
|
||||||||||||
|
|
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 : |
|
||||||
|
|
|
|
|
||||||
|
|
|
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 : |
|
||||||||||||||||||
|
|
|
|
|
||||||||||||||||||
|
|
|||||||||||||||||||||
|
|
|
Pour
les dates et les heures : |
|
||||||||||||||||||
|
|
|
|
|
||||||||||||||||||
|
|
|
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 : |
|
||||||||||||||||||
|
|
|
|
|
||||||||||||||||||
|
|
|||||||||||||||||||||
|
|
|
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 : |
|
|
|
|||
|
|
|||
|
|
|||
|
|
|
Si
nous lançons la requête, la boite de dialogue suivante s'affiche : |
|
|
|
|||
|
|
|||
|
|
|||
|
|
|
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 : |
|
|
|
|||
|
|
|||
|
|
|||
|
|
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. |
|
|
|
|||
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.