SQL JOIN : des requêtes sur plusieurs tables de données

SQL JOIN est une opération dans les bases de données re­la­tion­nelles qui permet d’effectuer des requêtes sur plusieurs tables de bases de données. Les JOINs combinent les données stockées dans dif­fé­rentes tables et les exécutent sous forme filtrée dans une table de résultats.

Le principe SQL JOIN est basé sur l’opération d’algèbre re­la­tion­nelle du même nom : il s’agit d’une une com­bi­nai­son de produit cartésien et de sélection. L’uti­li­sa­teur détermine les données des tables de sortie qui doivent être trans­fé­rées à la table des résultats en sé­lec­tion­nant un type de JOIN et en dé­fi­nis­sant une condition de sélection.

Nous vous pré­sen­te­rons les bases ma­thé­ma­tiques de SQL JOINs, com­pa­re­rons dif­fé­rents types de JOINs et vous mon­tre­rons comment im­plé­men­ter des JOINs dans des requêtes de base de données via SQL à l’aide d’exemples pratiques.

Conseil

Notre article sur SQL JOIN nécessite la con­nais­sance de certains concepts du modèle de base de données re­la­tion­nelle pour être compris, notamment en ce qui concerne les relations, les tuples, les attributs ou les clés. Pour en savoir plus, vous pouvez consulter notre article d’in­tro­duc­tion aux fon­da­men­taux des bases de données re­la­tion­nelles.

Comment fonc­tion­nent les SQL JOINs ?

Le principe de base de SQL-JOIN peut être illustré en faisant dériver l’opération de la base de données de ses sous-opé­ra­tions. Chaque JOIN est basé sur les opé­ra­tions d’algèbre re­la­tion­nelle suivantes :

  • Le produit cartésien
  • La sélection

Le produit cartésien

Le produit cartésien (ou produit croisé) est une opération de la théorie des ensembles dans laquelle deux ou plusieurs ensembles sont liés ensemble. Dans le modèle de base de données re­la­tion­nelle, le produit cartésien est utilisé pour relier des ensembles de n-tuples sous forme de tables. Le résultat de cette opération est à nouveau un ensemble de tuples ordonnés, où chaque tuple est constitué d’un élément de chaque ensemble initial.

Dans l’algèbre re­la­tion­nelle, le signe de mul­ti­pli­ca­tion (×) est utilisé comme opérateur du produit cartésien.

Un exemple pour illustrer :

Le produit cartésien A × B des deux ensembles A = {x, y, z} et B = {1, 2, 3} est :

A × B = {(x,1), (x,2), (x,3), (y,1), (y,2), (y,3), (z,1), (z,2), (z,3)}

Le graphique suivant permet d’y voir clair :

La séquence de formation des couples doit être respectée. Par exemple, le produit cartésien A × B ne cor­res­pond pas au même ensemble que le produit cartésien B × A.

A × B = {(x,1), (x,2), (x,3), (y,1), (y,2), (y,3), (z,1), (z,2), (z,3)}

B × A = {(1,x), (1,y), (1,z), (2,x), (2,y), (2,z), (3,x), (3,y), (3,z)}

Dans la ter­mi­no­lo­gie SQL, une opération dans laquelle le produit cartésien est formé à partir de deux tables de base de données est appelée CROSS JOIN. Dans la pratique, les CROSS JOINs sont rarement utilisés en raison de l’ensemble des résultats non filtrés.

La sélection

La sélection est une opération d’algèbre re­la­tion­nelle qui permet de sé­lec­tion­ner des tuples spé­ci­fiques à partir d’un ensemble initial et de les sortir comme un ensemble de résultats. Une com­pa­rai­son des ex­pres­sions peut être utilisée pour dé­ter­mi­ner quels tuples sont inclus dans l’ensemble de résultats. Le résultat de la sélection est donc un ensemble de tuples qui rem­plis­sent la condition de sélection définie dans la com­pa­rai­son des ex­pres­sions. La lettre grecque Sigma (σ) est utilisée comme opérateur. L’opération est notée comme suit :

σF (R)

Le caractère de rem­plis­sage "F" cor­res­pond à la com­pa­rai­son des ex­pres­sions, une formule de prédicats logiques qui dé­fi­nis­sent la condition de sélection. R re­pré­sente l’ensemble de données à sé­lec­tion­ner. Vous pouvez également utiliser la notation linéaire R[F].

Pour formuler les con­di­tions de sélection, vous pouvez avoir recours aux opé­ra­teurs de com­pa­rai­son habituels : par exemple, égal à (=), supérieur à (>) ou inférieur à (<).

Voici une ex­pli­ca­tion de la sélection à l’aide d’un exemple que nous avons déjà introduit dans notre texte sur les fon­da­men­taux des modèles de base de données re­la­tion­nelle. Le tableau suivant présente des données fictives qu’une en­tre­prise aurait pu saisir sur ses salariés. Pour chaque salarié, le matricule (e_id), l’identité (nom, prenom), le numéro d’assurance sociale (numsecu), l’adresse (rue, nr, code-postal, ville) et la voiture de fonction affectée (car_id) sont indiqués.

Table : salaries

e_id nom prénom numsecu rue nr code_postal ville car_id
1 Dupond Jacques 25 120512 S 477 Rue du soleil 1 11111 Lacité 3
2 Martin Jean 25 100615 M 694 Rue des champs 2 22222 Laville 1
3 Petit Hélène 25 091225 M 463 Rue des étoiles 3 33333 Levillage 1
4 Lefevre Lisa 25 170839 K 783 Rue de la mer 4 44444 Laforêt 2

Si nous voulons sé­lec­tion­ner le tableau « salaries » de telle sorte que seuls les salariés con­dui­sant la voiture de fonction car_id 1 soient affichés, nous pouvons procéder comme suit :

Σcar_id=1(salaries)

On récupère sim­ple­ment les tuples où la valeur de la colonne car_id est égale à 1.

Le résultat cor­res­pond au tableau suivant :

Table : salaries (sélection)

e_id nom prénom numsecu rue nr code-postal ville car_id
2 Martin Jean 25 100615 M 694 Rue des champs 2 22222 Laville 1
3 Petit Hélène 25 091225 M 463 Rue des étoiles 3 33333 Levillage 1

Dans le langage de base de données SQL, les con­di­tions de sélection sont définies à l’aide de la commande WHERE.

SELECT * FROM salaries WHERE salaries.car_id = 1;

Si un tuple remplit la condition car_id = 1, les valeurs de toutes les colonnes doivent être éditées pour ce tuple.

Note

L’as­té­risque (*) re­pré­sente toutes les colonnes d’une table dans le SQL Syntax.

Com­bi­nai­son du produit cartésien et de la sélection

Tous les types de JOIN usuels combinent le produit cartésien avec une condition de sélection. Afin d’expliquer le fonc­tion­ne­ment d’une telle base de données, nous réduisons le tableau « salaries » à quatre colonnes par souci de clarté. En outre, nous vous pré­sen­tons le tableau « car », dans lequel vous trouverez des in­for­ma­tions dé­tail­lées sur les types de véhicules détenus par l’en­tre­prise.

Les deux tables sont liées l’une à l’autre par une relation de clé étrangère. La clé primaire de la table « car » (car_id) agit comme une clé étrangère dans la table « salaries ».

Table : salaries

e_id nom prénom car_id
1 Dupond Jacques 3
2 Martin Jean 1
3 Petit Hélène 1
4 Lefevre Lisa 2

Tableau : car

car_id marque modèle im­ma­tri­cu­la­tion cons­truc­tion dé­par­te­ment
1 VW Caddy B KH 778 2016 75
2 Opel Astra B PO 654 2010 41
3 BMW X6 B MW 780 2017 37
Note

L’ex­ter­na­li­sa­tion des in­for­ma­tions de dif­fé­rentes tables de base de données est un concept essentiel à connaître sur les modèles de base de données re­la­tion­nelle. Ses avantages et sa mise en œuvre sont détaillés dans notre article sur la nor­ma­li­sa­tion des bases de données re­la­tion­nelles.

Si vous voulez fusionner les deux tables et sé­lec­tion­ner les tuples per­ti­nents à votre projet en même temps, vous pouvez combiner les opé­ra­tions de base de données pré­cé­dem­ment in­tro­duites :

σcar_id=car_id(salaries × car)

Tout d’abord, le produit cartésien salaries × car est formé. Le résultat (in­ter­mé­diaire) est un CROSS JOIN - un tableau de résultats dans lequel chaque tuple de la table "salaries" est combiné avec chaque tuple de la table "car".

Table : produit cartésien « salaries » × « car »

e_id nom prénom salaries.car_id car.car_id marque modèle im­ma­tri­cu­la­tion cons­truc­tion dép.
1 Dupond Jacques 3 1 VW Caddy B KH 778 2016 75
1 Dupond Jacques 3 2 Opel Astra B PO 654 2010 41
1 Dupond Jacques 3 3 BMW X6 B MW 780 2017 37
2 Martin Jean 1 1 VW Caddy B KH 778 2016 75
2 Martin Jean 1 2 Opel Astra B PO 654 2010 41
2 Martin Jean 1 3 BMW X6 B MW 780 2017 37
3 Petit Hélène 1 1 VW Caddy B KH 778 2016 75
3 Petit Hélène 1 2 Opel Astra B PO 654 2010 41
3 Petit Hélène 1 3 BMW X6 B MW 780 2017 37
4 Lefevre Lisa 2 1 VW Caddy B KH 778 2016 75
4 Lefevre Lisa 2 2 Opel Astra B PO 654 2010 41
4 Lefevre Lisa 2 3 BMW X6 B MW 780 2017 37

Ensuite, seuls les tuples pour lesquels le car_id de la table "car" cor­res­pond au car_id de la table "salaries" sont sé­lec­tion­nés. La condition de sélection est que la clé étrangère de la table "salaries" cor­res­ponde à la clé primaire de la table "car".

Le résultat (final) est une table qui fusionne les deux tables sans re­don­dance.

Table : JOIN sur « salaries » et « car »

e_id nom prénom salaries.car_id car.car_id marque modèle im­ma­tri­cu­la­tion cons­truc­tion dép.
1 Dupond Jacques 3 3 BMW X6 B MW 780 2017 37
2 Martin Jean 1 1 VW Caddy B KH 778 2016 75
3 Petit Hélène 1 1 VW Caddy B KH 778 2016 75
4 Lefevre Lisa 2 2 Opel Astra B PO 654 2010 41

Avec la com­bi­nai­son d’un produit cartésien et la sélection ul­té­rieure, les JOINs combinent les deux opé­ra­tions en une seule. Le symbole bowtie (⋈) est utilisé comme opérateur.

Voici l’ap­pli­ca­tion :

σcar_id=car_id(salaries × car) := salaries⋈car_id=car_idcar

L’opération σcar_id=car_id(salaries × car) cor­res­pond à un JOIN via les tables "salaries" et "car" avec la condition car_id=car_id.

Trans­fé­rée à la syntaxe SQL, l’opération ci-dessus cor­res­pon­drait à l’ins­truc­tion suivante :

SELECT * FROM salaries INNER JOIN car ON salaries.car_id = car.car_id;

L’INNER JOIN est l’un des JOIN utilisés les plus im­por­tants pour les requêtes dans les bases de données. Parfois, cependant, des types de JOIN spéciaux sont né­ces­saires pour obtenir le résultat désiré.

Les types de SQL JOIN

Dans le modèle de base de données re­la­tion­nelle, dif­fé­rents types de SQL JOIN sont utilisés. Ils per­met­tent d’exécuter des requêtes en groupant des tables de base de données. La condition préalable est que les tables sé­lec­tion­nées soient liées les unes aux autres à l’aide de relations clés étran­gères.

Les types de JOIN les plus im­por­tants sont les suivants :

  • INNER JOINs : un INNER JOIN est une forme filtrée du CROSS JOIN dans laquelle seuls les tuples des deux tables de sortie qui rem­plis­sent la condition de sélection définie par l’uti­li­sa­teur sont fusionnés dans le jeu de résultats.
  • OUTER JOINs : le OUTER JOIN est une extension de l’INNER JOIN. L’ensemble de résultats d’un OUTER JOIN contient les tuples des deux tables de sortie qui rem­plis­sent la condition de sélection définie par l’uti­li­sa­teur, ainsi que tous les tuples restants de la première table, de la deuxième table, ou des deux tables. Les OUTER JOINS sont par con­sé­quent im­plé­men­tés comme LEFT OUTER JOIN, RIGHT OUTER JOIN ou FULL OUTER JOIN.

Les dif­fé­rences entre les INNER JOINs et les dif­fé­rentes variantes des OUTER JOINS peuvent être il­lus­trées par un schéma re­pré­sen­tant les ensembles. Le graphique suivant illustre les types de JOIN présentés :

In­dé­pen­dam­ment de la dis­tinc­tion entre INNER JOIN et OUTER JOIN, les SQL JOIN peuvent également être classés comme les types de JOIN suivants :

  • EQUI JOIN
  • NON EQUI JOIN
  • SELF JOIN

Les INNER JOINs et OUTER JOINs peuvent être im­plé­men­tés comme EQUI JOINs et NON EQUI JOINs. Tous les exemples de JOIN présentés jusqu’à présent sont des EQUI JOINs. Les EQUI JOINs se ca­rac­té­ri­sent par le fait qu’ils n’au­to­ri­sent que le signe égal comme opérateur de com­pa­rai­son (=).

La condition de sélection d’un EQUI JOIN est donc toujours l’égalité des valeurs des colonnes.

En principe, cependant, les JOINS (ainsi que la sélection en algèbre re­la­tion­nelle) ne sont pas limités à l’égalité des colonnes. Les opé­ra­teurs de com­pa­rai­son possibles sont :

Opérateur de com­pa­rai­son Sig­ni­fi­ca­tion
= égal
< Inférieur à
> Supérieur à
Inférieur ou égal
Supérieur ou égal
<> différent
!= différent

Depuis SQL-92 le langage de base de données offre avec USING un raccourci pour EQUI JOINS. Toutefois, cela suppose que les colonnes con­cer­nées par la ma­ni­pu­la­tion portent le même nom, ce qui n’est pas toujours le cas.

L’exemple suivant montre deux ins­truc­tions SQL dif­fé­rentes qui mènent au même résultat. Dans la première ins­truc­tion, l’opération JOIN est ex­pli­ci­te­ment définie par le mot-clé ON. Pour la deuxième, nous utilisons un raccourci avec USING.

SELECT * FROM salaries INNER JOIN car ON salaries.car_id = car.car_id;
SELECT * FROM salaries INNER JOIN car USING car_id;

NON EQUI JOINs, en revanche, excluent les opé­ra­tions basées sur l’égalité des colonnes. Ainsi, toutes les opé­ra­tions de com­pa­rai­son sont au­to­ri­sées à l’exception du signe égal (=).

Note

Puisque les relations dans les bases de données re­la­tion­nelles sont gé­né­ra­le­ment définies par l’égalité des clés primaires et étran­gères, NON EQUI JOIN est d’im­por­tance se­con­daire dans le modèle de base de données re­la­tion­nelle. D’autant plus que, comme pour les CROSS JOINs, ils con­dui­sent souvent à un grand nombre d’ensembles de données de résultats.

Enfin, un SELF JOIN est une forme spéciale de SQL-JOIN dans laquelle une table de base de données est liée à elle-même. En principe, n’importe quel type de JOIN peut être exécuté comme un SELF JOIN.

Si deux tables sont liées par des colonnes du même nom, on parle de NATURAL JOIN. Un NATURAL JOIN est im­plé­menté par défaut comme INNER JOIN avec le mot-clé du même nom. Les NATURAL JOIN ne sont toutefois pas fixés à ce type de JOIN. On peut également avoir un NATURAL LEFT OUTER JOIN ou NATURAL RIGHT OUTER JOIN.

Comme les NATURAL JOINs sont liés par des colonnes du même nom, les valeurs res­pec­tives ne sont pas éditées deux fois dans le jeu de résultats, mais sont fu­sion­nées pour former une colonne commune. Des exemples de NATURAL JOINs sont dis­po­nibles dans les articles sur les INNER JOINs et OUTER JOINs.

Aller au menu principal