|
1 - Introduction |
|
| |
|
Dans une base de données relationnelle, les informations sont réparties sur un grand nombre de tables. Il est donc
fréquent qu'une requête porte sur deux tables (ou plus), liées par une (ou plusieurs) relation(s). La notion de
jointure précise comment fonctionnent cette (ou ces) relation(s) lors de l'exécution de la requête. |
|
|
|
Comme pour les autres chapitres de ce tutoriel (ou tutorial, ou cours en ligne), nous utilisons le SGBD Access comme support
pratique. Pour bâtir un exemple, nous faisons appel aux deux tables "Personnes" et "Communes" dont nous nous sommes
déjà servis au chapitre 4. Nous remplissons ces deux tables comme le montre la figure ci-dessous. Précisons que le champ
"Commune" de la table "Personnes" n'a pas été rendu obligatoire (le Null est autorisé), si bien qu'il peut arriver
qu'une commune ne soit pas attribuée à une personne, comme c'est le cas pour Jeanne Dupont. |
|
|
| Nom |
Prénom |
Commune |
| Truc |
Jean |
Grenoble |
| Chose |
Pierre |
Nancy |
| Machin |
Noémie |
Uriage |
| Dupont |
Jeanne |
|
|
|
| Commune |
Code postal |
| Grenoble |
38000 |
| Grenoble |
38001 |
| Nancy |
54000 |
| Uriage |
38410 |
| SMH |
38402 |
|
|
|
| Table "Personnes" |
Table "Communes" |
|
|
|
|
Les deux tables sont liées par une relation, assurée via un code masqué. Cette relation apparaît dans la fenêtre
"Relations", comme le montre la figure ci-dessous. |
|
|
 |
|
|
2 - La relation |
|
| |
|
Si nous ajoutons les deux tables précitées à la fenêtre de création d'une requête, nous constatons que la relation qui
les lie est toujours présente. |
|
|
|
Dans la fenêtre de création d'une requête, nous pouvons supprimer cette relation. La procédure est identique à celle
pratiquée dans la fenêtre "Relations" : nous effectuons un clic droit sur la relation, et nous choisissons
"Supprimer". Nous fermons la fenêtre de création de la requête, et nous enregistrons cette dernière. |
|
|
|
Si nous ouvrons la fenêtre "Relations", nous constatons que la relation qui lie les deux tables existe
toujours. Cette relation est en quelque sorte une propriété des deux tables. |
|
|
|
La suppression que nous avons effectuée est liée à une requête particulière. Elle n'a d'effet que lors de
l'exécution de la requête. Ce n'est pas une propriété des deux tables, mais une propriété de la requête. |
|
|
|
En conclusion, les opérations que nous effectuons sur les relations (création, suppression, modification des propriétés)
ont un effet : |
|
|
|
| |
|
permanent lorsqu'elles sont effectuées dans la fenêtre "Relations" ; |
|
|
éphémère lorsqu'elles sont effectuées dans la fenêtre de création d'une requête particulière. |
|
|
|
|
Remarque : même s'il n'existe pas de relation entre deux tables, le SGBD Access en crée une automatiquement lorsque vous ajoutez ces
deux tables à la fenêtre de création d'une requête, à condition que ces tables aient chacune un champ du même nom et du même type de
données, et qu'un des deux champs possède une clé primaire. |
|
|
|
3 - Le produit vectoriel |
|
| |
|
Nous rouvrons la requête précédente en mode "Modification". Nous vérifions qu'aucune relation n'apparaît entre les
deux tables. Dans la grille, nous introduisons les champs "Nom" et "Prénom" de la première table, et les champs
"Commune" et "Code postal" de la seconde. La feuille de données résultante contient 20 lignes ! Que s'est-il
passé ? |
|
|
|
Le SGBD a associé chaque ligne de la première table (il y en a 4) à chaque ligne de la seconde (il y en a 5). On dit
qu'il a effectué le produit vectoriel des deux tables. L'absence de relation fait que le SGBD ne sait
pas comment il doit associer les lignes des deux tables ; de ce fait, il réalise toutes les combinaisons possibles. |
|
|
|
Il faut faire attention au fait que le produit vectoriel peut nous conduire à créer des tables gigantesques : le
produit de deux tables contenant chacune 1.000 enregistrements est une table possédant 1 million de lignes ! |
|
|
|
En pratique, on n'utilise pas le produit vectoriel, sauf dans des cas très rares, comme par exemple pour réunir dans une seule
table des comptages isolés. Ces derniers se présentent en effet sous forme de tables à une seule ligne, et l'on peut en faire le produit
vectoriel sans risque, car le résultat est alors une table à une seule ligne. |
|
|
|
4 - La jointure interne |
|
| |
|
Dans la fenêtre de création de la requête, nous rétablissons la relation entre les deux tables. Cette fois, la feuille
de données résultante ne contient plus que 3 lignes, comme le montre la figure ci-dessous. |
|
|
| Nom |
Prénom |
Commune |
Code postal |
| Truc |
Jean |
Grenoble |
38000 |
| Chose |
Pierre |
Nancy |
54000 |
| Machin |
Noémie |
Uriage |
38410 |
|
|
|
|
Nous constatons que ne figurent dans la table résultante que les enregistrements qui sont présents dans les deux tables. La
personne Dupont Jeanne, dont la commune n'est pas précisée, est absente du résultat. Les villes Grenoble (38001) et SMH, auxquelles ne
correspond aucune personne, sont également absente. Le SGBD a traité la relation entre les deux tables comme une
jointure interne. |
|
|
|
Effectuons un clic droit sur la relation, et sélectionnons "Propriétés de la jointure". La fenêtre du même nom
s'affiche ; elle se présente comme le montre la figure ci-dessous. Bien que le terme ne soit pas présent, l'option 1 de la
fenêtre correspond effectivement à la jointure interne. |
|
|
 |
|
|
|
Remarque : dans la requête précédente, le champ "Commune" est issu de la table "Communes". S'il provenait
de la table "Personnes", le résultat s'afficherait de la même façon. C'est seulement en exportant la table que l'on peut
s'apercevoir que dans le second cas, le champ contient un code au lieu d'un nom de commune. |
|
|
|
5 - La jointure gauche |
|
| |
|
La fenêtre "Propriétés de la jointure", représentée ci-dessus, nous fournit deux autres options. Nous activons le
bouton 2 et nous validons par "OK". La requête se présente maintenant comme le montre la figure ci-dessous. Nous avons
affaire à une jointure gauche. Pour le signaler, la liaison prend la forme d'une flèche... dirigée
vers la droite. |
|
|
 |
|
|
|
Si nous basculons en mode feuille de données, nous obtenons le résultat suivant : |
|
|
| Nom |
Prénom |
Commune |
Code postal |
| Truc |
Jean |
Grenoble |
38000 |
| Chose |
Pierre |
Nancy |
54000 |
| Machin |
Noémie |
Uriage |
38410 |
| Dupont |
Jeanne |
|
|
|
|
|
|
Cette fois, le SGBD a conservé tous les enregistrements de la table "Personnes", et il leur a associé les
enregistrements disponibles dans la table "Communes". Comme nous n'avons pas précisé de critère de sélection, tous ces
enregistrements ont été conservés. |
|
|
|
6 - La jointure droite |
|
| |
|
Dans la fenêtre "Propriétés de la jointure", nous activons le bouton 3 et nous validons par "OK".
Nous avons maintenant affaire à une jointure droite. Pour le signaler, la liaison prend la forme d'une
flèche... dirigée vers la gauche. |
|
|
|
Si nous basculons en mode feuille de données, nous obtenons le résultat suivant : |
|
|
| Nom |
Prénom |
Commune |
Code postal |
| Truc |
Jean |
Grenoble |
38000 |
|
|
Grenoble |
38001 |
| Chose |
Pierre |
Nancy |
54000 |
| Machin |
Noémie |
Uriage |
38410 |
|
|
SMH |
38402 |
|
|
|
|
Cette fois, le SGBD a conservé tous les enregistrements de la table "Communes", et il leur a associé les
enregistrements disponibles dans la table "Personnes". Comme nous n'avons pas précisé de critère de sélection, tous ces
enregistrements ont été conservés. |
|
|
|
Conclusion : le résultat d'une requête multi-table dépend du type de jointure choisi. Par
défaut, c'est la jointure interne qui s'applique. |
|
|
|
7 - La requête de non correspondance |
|
| |
|
La requête de non correspondance constitue une application importante de la notion de
jointure. Elle met en jeu deux tables ayant en commun un champ possédant le même type de données, et doté des mêmes propriétés (mais pas
forcément du même nom). La requête de non-correspondance ne conserve un enregistrement de la première table que si le contenu du champ
n'est pas présent dans la seconde table. Les deux tables n'ont pas besoin d'être liées au préalable par une relation, cette dernière
sera créée en même temps que la requête. |
|
|
|
Pour construire un exemple simple, nous créons deux tables à un seul champ, contenant des prénoms, et intitulées
"Prénoms1" et "Prénoms2". Les tables se présentent ainsi : |
|
|
| Prénom |
| Paul |
| Jean |
| Marie |
| Henri |
| Claude |
|
|
| Prénom |
| Henri |
| Patrick |
| Paul |
|
|
|
| "Prénoms1" |
"Prénoms2" |
|
|
|
|
Nous recherchons les prénoms de la première table qui sont absents de la seconde. Pour ce faire, nous devons passer en revue
tous les prénoms de la première table, et regarder s'ils sont ou non dans la seconde. Pour créer la requête correspondante,
nous songeons donc à utiliser une jointure gauche. |
|
|
|
Pour bien comprendre ce qui se passe, nous pouvons décomposer en deux temps le fonctionnement de la requête. D'abord,
le SGBD sélectionne tous les prénoms de la première table, et leur associe les prénoms de la seconde table quand il sont
identiques. Le résultat de cette première étape peut être représenté ainsi : |
|
|
| Prénom1 |
Prénom2 |
| Paul |
Paul |
| Jean |
|
| Marie |
|
| Henri |
Henri |
| Claude |
|
|
|
|
|
Il faut maintenant que le SGBD applique un critère de sélection, pour ne conserver que les lignes dont la deuxième colonne est
vide. Nous plaçons donc le critère "Est Null" dans la colonne relative au champ "Prénom" de la seconde table. |
|
|
|
En définitive, nous obtenons la requête représentée sur la figure ci-dessous (remarquez la flèche qui traduit la jointure
gauche). Nous avons supprimé l'affichage de la seconde colonne, car il conduirait à créer une colonne vide dans la feuille de données
résultante. |
|
|
 |
|
|
|
Si nous basculons en mode feuille de données, nous obtenons le résultat suivant : |
|
|
|
|
|
|
|
Il est indispensable, dans un requête de non correspondance, de ne pas se tromper sur le type de jointure à utiliser.
Ainsi, si nous choisissons la jointure interne (par défaut), le SGBD ne sélectionne que les prénoms qui sont simultanément présents
dans les deux tables. Le résultat de cette étape intermédiaire est représenté ci-dessous : |
|
|
| Prénom1 |
Prénom2 |
| Paul |
Paul |
| Henri |
Henri |
|
|
|
|
Lorsque nous appliquons le critère "Est Null" à la deuxième colonne, le SGBD ne conserve que les lignes pour
lesquelles la deuxième colonne est vide. Comme il n'y en a pas, la feuille de données résultante ne contient aucun enregistrement
-- ce que l'expérience confirme. |
|
|
|
Si nous utilisons la jointure droite, le SGBD sélectionne tous les prénoms de la seconde table, et seulement ceux de la
première table qui se trouvent dans la seconde. Cette étape intermédiaire peut être représentée ainsi : |
|
|
| Prénom1 |
Prénom2 |
| Paul |
Paul |
| Henri |
Henri |
|
Patrick |
|
|
|
|
Puis le SGBD élimine les lignes pour lesquelles la seconde colonne est vide. Comme il n'y en a pas, la feuille de
données résultante ne contient aucun enregistrement -- ce que l'expérience confirme. |
|
|
|
Si le raisonnement relatif à la requête de non correspondance vous paraît ardu, ne vous inquiétez pas : vous n'êtes pas
le seul. C'est la raison pour laquelle Microsoft a créé un assistant pour ce type de recherche. Vous le trouverez dans la fenêtre
"Base de données", l'objet "Requêtes" étant sélectionné. Vous cliquez sur l'icône
"Nouveau", et vous sélectionnez "Assistant Requête de
non-correspondance". |
|
|
|
8 - La requête de correspondance |
|
| |
|
La requête de correspondance est en quelque sorte le complément de la précédente. Elle met
en jeu deux tables ayant en commun un champ possédant le même type de données, et doté des mêmes propriétés (mais pas forcément du même
nom). Elle ne conserve un enregistrement de la première table que si le contenu du champ est présent dans la seconde table. La
requête de correspondance constitue elle aussi une application courante de la notion de jointure. Comme précédemment, les
deux tables n'ont pas besoin d'être liées au préalable par une relation, cette dernière étant créée en même temps que la requête. |
|
|
|
Cette fois, nous recherchons les prénoms de la première table qui sont présents dans la seconde. Pour créer la requête
correspondante, il nous faut utiliser une jointure interne. Cela suffit, il n'est pas utile de préciser un critère. Nous obtenons
ainsi la requête représentée sur la figure ci-dessous. |
|
|
 |
|
|
|
Si nous basculons en mode feuille de données, nous obtenons le résultat suivant, complémentaire de celui obtenu avec la
requête de non correspondance : |
|
|
|
|
|
|
|
Exercez-vous à prévoir ce qui se passe si vous vous trompez de jointure, et vérifiez si l'expérience confirme vos
prédictions. |
|
|
|
La requête de correspondance étant plus facile à créer que la requête de non-correspondance, l'éditeur d'Access n'a pas
prévu d'assistant pour aider à la créer. Cependant, vous pouvez utiliser l'assistant précédent, et changer simplement la condition
"Est Null" par son contraire "Est Pas Null". C'est inutilement compliqué, mais cela marche. |
|
|