No cache version.

Caching disabled. Default setting for this page:enabled (code LNG204)
If the display is too slow, you can disable the user mode to view the cached version.

SQL : Jointures

Nous avons vu en algèbre relationnelle ce qu'étaient les jointures. Nous allons nous pencher ici sur leur application en SQL.

Exemples de jointure

Nous pouvons nous passer des opérateurs JOIN, et utiliser des SELECT imbriqués. Par exemple, pour trouver le numéro des élèves de sexe féminin qui ont suivi le cours de gymnastique de Mr Mégot, nous pouvons effectuer la requête suivante :

  1. SELECT DISTINCT s.student_id FROM t_student s, t_course c
  2. WHERE s.gender='F'
  3. AND c.teacher_fk = (SELECT teacher_id FROM t_teacher WHERE UPPER(teacher_lastname) = 'MEGOT');

Ce type de requête était fort utilisé auparavant. Parfois, nous retrouvons même plusieurs requêtes exécutées à la suite dans une transaction.

Il est possible d'optimiser nettement notre requête par l'utilisation des jointures :

  1. SELECT DISTINCT s.student_id FROM t_student s, t_course c
  2. s.student_id = c.student_fk /* jointure entre t_student et t_course */
  3. AND c.teacher_fk = teacher_id /* jointure entre t_course et t_teacher */
  4. AND s.gender='F'
  5. AND UPPER(teacher_lastname) = 'MEGOT');

Il est possible de rendre cette requête beaucoup plus lisible :

  1. SELECT DISTINCT s.student_id FROM
  2. ( t_student s INNER JOIN course c ON s.student_id = c.student_fk )
  3. INNER JOIN t_teacher t ON t.teacher_id = c.teacher_fk
  4. WHERE s.gender='F'
  5. AND UPPER(teacher_lastname) = 'MEGOT';

Une jointure permet d'associer des colonnes de tables différentes pour étendre le champ des recherches, pour peu que chaque table contienne un champ dont les valeurs correspondent à celles d'une autre table. Dans le cadre de notre exemple, les valeurs du champ student_fk de la table t_course correspondent à des valeurs du champ student_id de la table t_student.

Remarque

Une jointure naturelle, ce peut sembler beaucoup plus lisible car les deux champs portent le même nom (par exemple t_student.student_id et t_course.student_id), mais la jointure fonctionne parfaitement même si les noms des champs sont différents (equi-jointure dans notre exemple, avec t_student.student_id et t_course.student_fk).

Pour ma part, je préfère utiliser le suffixe _fk qui permet de savoir facilement que nous sommes en présence d'un champs qui fait référence à une autre table (et qui est donc soumis à une contrainte de type Foreign key).

Autres types de jointures

Nous pouvons aussi trouver d'autres types de jointures :

  • Auto-jointure : jointure d'une table avec elle même dans le cas par exemple d'un système hiérarchique (un champ de la table référence un autre champ de cette même table).
  • Jointure hétérogène : jointure entre plusieurs bases de données.
  • Jointure externe : jointure qui permet de retourner une table sans concordance.
  • Jointure croisée : jointure qui retourne le produit cartésien de plusieurs tables.

Contents Haut

INNER JOIN

Un INNER JOIN est le type de jointure par défaut, qui retourne les enregistrements dont les valeurs comparées sont égales.

Nous pouvons représenter la jointure INNER JOIN par le schéma suivant :

INNER JOIN

Nous pouvons par exemple demander le nom et prénom des étudiants qui ont suivi un cours, ainsi que les dates et intitulés des cours suivis :

  1. SELECT s.student_lastname, s.student_firstname, c.course_start_date, c.course_name FROM
  2. t_student s INNER JOIN course c ON s.student_id = c.student_fk;
  • Nous n'avons pas la totalité des élèves, car ceux qui n'ont pas suivi de cours n'apparaissent pas.
  • Nous n'avons pas la totalité des cours, car nous n'avons pas les cours qui n'ont pas d'élèves (cours qui n'ont pas encore été donnés).

Contents Haut

LEFT JOIN

La jointure LEFT JOIN nous permet non seulement de demander les enregistrements dont les valeurs comparées sont égales, mais aussi la totalité des enregistrements de la table de gauche.

Nous pouvons représenter la jointure LEFT JOIN par le schéma suivant :

LEFT JOIN

Nous pouvons demander tous les noms des élèves ainsi que les dates et intitulés des cours suivis par certains de ces élèves :

  1. SELECT s.student_lastname, s.student_firstname, c.course_start_date, c.course_name FROM
  2. t_student s LEFT JOIN course c ON s.student_id = c.student_fk;

Cette requête différe seulement d'un mot par rapport à la précédente. En spécifiant que la requête comporte une jointure de type LEFT JOIN au lieu d'INNER JOIN, nous pouvons constater les effets suivants :

  • Nous avons la totalité des élèves, même ceux qui n'ont suivi aucun cours (aucune correspondance avec la table cours).
  • Nous n'avons pas la totalité des cours, car nous n'avons pas les cours qui n'ont pas d'élèves.

Contents Haut

RIGHT JOIN

La jointure RIGHT JOIN repose sur le même principe que la jointure LEFT JOIN, mais c'est la totalité des enregistrements de la table de droite qui est retournée en plus des éléments qui satisfont à l'égalité.

RIGHT JOIN

Nous pouvons demander tous les noms des élèves qui ont suivi au moins un cours, et l'ensemble des dates et intitulés de tous les cours :

  1. SELECT s.student_lastname, s.student_firstname, c.course_start_date, c.course_name FROM
  2. t_student s RIGHT JOIN course c ON s.student_id = c.student_fk;
  • Nous avons seulement les élèves qui ont suivi au moins un cours.
  • Nous avons la totalité des cours, y compris ceux qui n'ont été donnés à aucun de ces élèves.

JOIN et les SGBD

Les jointures sont vivement conseillées, mais nous devons préalablement vérifier que la base de données supporte ce type de requête. Voici un petit résumé de la situation :

  • Oracle : depuis la version 9.
  • MySQL :
    • INNER JOIN depuis la version 3.23.17
    • UNION et CROSS JOIN depuis la version 4.0.11
  • PostGreSQL : LEFT et RIGHT seulement.
  • DB2 : LEFT seulement

Depuis la création de ce document, la prise en charge de ces opérateurs par les SGBD cités est peut-être plus étendue.

English translation

You have asked to visit this site in English. For now, only the interface is translated, but not all the content yet.

If you want to help me in translations, your contribution is welcome. All you need to do is register on the site, and send me a message asking me to add you to the group of translators, which will give you the opportunity to translate the pages you want. A link at the bottom of each translated page indicates that you are the translator, and has a link to your profile.

Thank you in advance.

Document created the 17/03/2007, last modified the 01/11/2018
Source of the printed document:https://www.gaudry.be/en/sql-join.html

The infobrol is a personal site whose content is my sole responsibility. The text is available under CreativeCommons license (BY-NC-SA). More info on the terms of use and the author.