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.
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.
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.
Attention : Le 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.
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é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 :
Prénom |
---|
Jean |
Marie |
Claude |
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 :
Prénom |
---|
Henri |
Paul |
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.9 - Conclusion
La notion de jointure joue un rôle important dans les requêtes multi-tables, en particulier dans les requêtes de correspondance et de non correspondance.Si l'opérateur ne précise pas le type de jointure, c'est la jointure interne que le SGBD applique par défaut.
Aucun commentaire:
Enregistrer un commentaire