Informatique


Jointures (1-1)(1-n)

Objectifs
Sélectionner des tuples dans des tables jointes par une relation (1-1)(1-n)

Utilisation et exemple

On utilise les jointures lorsque l'on veut sélectionner des champs sur plusieurs tables qui sont mises en relation.

Soit les tables client, categorie et commune que nous avons utilisées pour la requête d'insertion (1-1)(1-n):

Le MCD:

Le MLD:

client: id_cli, nom_cli, preno_cli, adres_cli, id_cat, id_com
categorie: id_cat, nom_cat, pourc_cat
commune: id_com, nom_com, codep_com

Si nous voulons afficher le nom du client, sa catégorie et sa commune de résidence nous devons:

  • sélectionner le nom dans la table client
  • récupérer l'id de la catégorie du client dans la table client
  • sélectionner la catégorie du client dans la table catégorie
  • récupérer l'id de la commune du client dans la table client
  • sélectionner la commune du client dans la table commune
  • C'est un peu long isn't it?

On va tout faire en une seule commande, beter nee?

Principe des jointures

Imaginons les occurences suivantes au sein de nos trois tables:

id_cli nom_cli preno_cli adres_cli id_cat id_com
1 Vandeput Mohamed rue Zbé 69 3 2
2 El Ajoui Stéphanie rue d'Aerschot 96 2 5
3 Martel Charles rue de la Liberté 1 1 4
4 Marie-Martine Simple rue Doof 17 2 4
---------------------------------------------------------
id_cat nom_cat pourc_cat
1 Parastatal 20
2 Particulier 0
3 Société 15
4 ASBL 15
--------------------------------------------
id_com nom_com codep_com
1 Bruxelles 1000
2 Schaerbeeck 1030
3 Auderghem 1160
4 Ixelles 1140
5 Molenbeeck 1180

Quand on fait une jointure, on crée une table virtuelle et temporaire qui reprend toutes les colonnes des tables liées, donc:

id_cli nom_cli preno_cli adres_cli id_cat id_com   id_cat nom_cat pourc_cat   id_com nom_com codep_com
1 Vandeput Mohamed rue Zbé 69 3 2   3 Société 15   2 Schaerbeeck 1030
2 El Ajoui Stéphanie rue d'Aerschot 96 2 5   2 Particulier 0   5 Molenbeeck 1180
3 Martel Charlesz rue de la Liberté 1 1 4   1 Parastatal 20   3 Auderghem 1160
4 Marie-Martine Simple rue Doof 17 2 5   2 Particulier 0   2 Schaerbeeck 1130

On constate que la table virtuelle a aligné sur une même ligne les occurences liées, dès ce moment on peut parcourir chaque ligne et tirer les informations de notre choix.

Les jointures internes

Une jointure interne est une jointure pour laquelle il y a une donnée équivalente de part et d'autre de la jointure.

Dans notre exemple, on constate que les tables client et categorie partagent la donné id_cat, les tables client et commune partagent la donnée id_com.

  • on précise d'abord les champs que l'on veut récupérer, ils peuvent provenir des trois tables
  • from: de la première table, client, celle sur laquelle on travaille
  • inner join: permet de joindre la table categorie à la table client
  • on: sur le critère: l'égalité entre les id_cat des tables client et categorie
  • inner join: permet de joindre la table commune à la table client
  • on: sur le critère: l'égalité entre les id_com des tables client et commune
  • WHERE: dans la table virtuelle je sélectionne les lignes qui ont la valeur "Particulier" par exemple

$req = " select nom_cli, nom_cat, nom_com
from  client
inner join categorie
on client.id_cat= categorie.id_cat
inner join commune
on client.id_com = commune.id_com
WHERE nom.cat = "Particulier"
";

On utilise souvent une syntaxe particulière, celle du "surnommage": on surnomme client en CL, catégorie en CA et commune CO:

$req = " select nom_cli, nom_cat, nom_com
from  client CL
inner join categorie CA
on CL.id_cat= CA.id_cat
inner join commune CO
on CL.id_com = CO.id_com
WHERE nom.cat = "Particulier"
";

Les clause where, order by et limit sont bien sûr toujours valables:

Nous voulons toujours récupérer les nom, catégorie et commune des clients mais uniquement pour ceux dont le nom commence par la lettre "L", on désire un résultat par ordre alphabétique sur le nom du client:

$req = " select nom_cli, nom_cat, nom_com
from  client CL
inner join categorie CA
on CL.id_cat= CA.id_cat
inner join commune CO
on CL.id_com = CO.id_com
where CL.nom_cli> 'L'&& CL.nom_cli < 'M'
order by CL.nom_cli asc
";

Les clauses where, order by et limit se placent après les jointures.

Les jointures externes

Les jointures externes, en plus de sélectionner l'ensemble des lignes des tables respectant le critère de jointure comme le font les jointures internes, elles sélectionnent aussi les données d'une des tables qui ne respectent pas le critère de jointure.

Il existe des jointures par la gauche et des jointures par la droite.

Comment les distinguer?

C'est simple!

Lorsqu'on fait une jointure par la gauche, cela signifie que l'on veut toutes les lignes de la tables de gauche, celle qui suit le mot FROM, même si celles-ci n'ont pas de correrspondance avec une ligne de la table de droite.

Lorsqu'on fait une jointure par la droite, c'est exactement l'inverse, cela signifie que l'on veut toutes les lignes de la tables de droite, même si celles-ci n'ont pas de correrspondance avec une ligne de la table de gauche, celle qui suit le mot FROM.

LEFT JOIN

Le left join implique que l'on sélectionne toutes les lignes respectant le critère de jointure, puis on ajoute toutes les lignes de la table "TableGauche" qui ont été rejetées car elles ne respectaient pas le critère de jointure.

Imaginons un client pour lequel la catégorie n'a pas été enregistrée, par exemple car nous n'avons pas encore cette information, et dont nous voulons afficher quand même les informations:

$req = " select nom_cli, nom_cat, nom_com
from  client CL
left join categorie CA
on CL.id_cat= CA.id_cat
inner join commune CO
on CL.id_com = CO.id_com
";

RIGHT JOIN

Le right join implique que l'on sélectionne toutes les lignes respectant le critère de jointure, puis on ajoute toutes les lignes de la table "TableDroite" qui ont été rejetées car elles ne respectaient pas le critère de jointure.

Imaginons un client pour lequel la catégorie n'a pas été enregistrée, par exemple car nous n'avons pas encore cette information, et dont nous voulons afficher quand même les informations. En plus nous avons un code postal auquel nous n'avons pas de client et nous voulons l'afficher:

$req = " select nom_cli, nom_cat, nom_com
from  client CL
left join categorie CA
on CL.id_cat= CA.id_cat
right join commune CO
on CL.id_com = CO.id_com
";