SQL - requêtesRequêtes sur plusieurs tables

Il existe plusieurs méthodes pour relier des tables entre elles. Certaines permettent de les associer en prenant en compte des contraintes sur des attributs, les jointures, certaines les associent sans trop regarder ce qu'il se passe, les produits cartésiens.

Les jointures

Comme dit précédemment, les jointures vont permettre de relier deux tables entre elles. On les a vu également en algèbre relationnelle. Le fonctionnement est pratiquement le même, à l'exception près qu'ici il faut spécifier l'attribut de jointure, même si dans les deux tables celui-ci a le même nom.
Reprenons l'exemple de notre base de données à trois tables.
Nom, prénom des persones et département dans lequel elles travaillent:
AR: πnom,prenom,dept(Personne ∞ Travaillent)

  1. mysql> select nom,prenom,dept from personne, travaillent where personne.nss = travaillent.nss;
  2. mysql> select nom,prenom,dept from personne inner join travaillent on personne.nss = travaillent.nss;
Vous remarquez qu'on peut utiliser deux méthodes pour appliquer une jointure.
La jointure est directement appliquée dans la condition where. L'avantage est que l'on met toutes nos tables dans le from et toutes nos jointures ensemble dans le where. L'inconvénient est qu'il est plus facile de passer à côté d'une jointure, et qu'il faut également bien penser à séparer les jointures du reste des contraintes pour éviter toute confusion
Les tables sont reliées en utilisant inner join. L'avantage est que chaque jointure est clairement définie et que l'on suit le cheminement de no associations au fur et à mesures des jointures. L'inconvénient est qu'il faut bien spécifier les jointures dans le bon ordre pour éviter des erreurs

Nous allons plus nous pencher sur les jointures de type join dans ce cours, car en mysql elle permettent de faire plus de choses. Il n'en est pas forcément de même avec d'autres SGBD, notamment Oracle qui es le plus complet des SGBD.

Je vous rappelle cela car c'est TRES important! Quand vous faites des jointures sur des attributs ayant le même nom, pensez bien à préfixer l'attribut par le nom de la table. Vous pouvez le faire même si ce sont des attributs avec des noms différents donc habituez-vous à le faire tout le temps.

Pour expliquer les différents types de jointures auxquels nous allons faire face, prenons un nouvel exemple simple.
prof
cours

La jointure simple inner join
Elle consiste à associer les deux tables sur un ou plusieurs attributs en commun.
  1. mysql> select * from prof, cours where prof.id_p = cours.id_p;
  2. mysql> select * from prof inner join cours on prof.id_p = cours.id_p;

Ici, seuls les éléments des deux tables pouvant être conservés dans le résultat final sont gardés. Ainsi ni les profs 5 et 6 ne donnant pas de cours, ni le cours 6 ne seront représentés dans le résultat de la jointure.

La jointure complexe left join
S'il y a une ligne dans A qui répond à la clause where, mais qu'il n'y a aucune ligne dans B qui répond à la condition du LEFT JOIN, alors une ligne supplémentaire de B est générée avec toutes les colonnes mises à null.

  1. mysql> select * from prof left join cours on prof.id_p = cours.id_p;


La jointure complexe right join
S'il y a une ligne dans B qui répond à la clause where, mais qu'il n'y a aucune ligne dans A qui répond à la condition du RIGHT JOIN, alors une ligne supplémentaire de A est générée avec toutes les colonnes mises à NULL .

  1. mysql> select * from prof right join cours on prof.id_p = cours.id_p;


La jointure complexe full (outer) join
C'est une combinaison des 2 précédentes, non nativement supporté par mysql (où elle est remplacée par une opération d'union)

  1. mysql> select * from prof left join cours on prof.id_p = cours.id_p union select * from prof right join cours on prof.id_p = cours.id_p;


La jointure complexe full (outer) join
Voilà deux exemples avec nos 3 tables personnes, travaillent, departement.
  1. mysql> # nom, prénom, adresse des département, activité
  2. mysql> select * from personnes
  3. inner join travaillent on peronnes.nss = travaillent.nss
  4. inner join departement on travaillent.dep = departement.dep;
  5. mysql> # nss, adresse des département des personnes dont le nom commence par R
  6. mysql> select personnes.nss, adresse from personnes
  7. inner join travaillent on peronnes.nss = travaillent.nss
  8. inner join departement on travaillent.dep = departement.dep
  9. where nom like 'R%';

On voit dans le second exemple qu'on affiche uniquement des attributs des tables personnes de departements, mais on utilise tout de même la table travaillent pour relier les deux autres. De plus, on doit spécifier de quelle table on sélectionne nss, sinon on aura une erreur dite erreur d'ambiguité.

Vous voyez, il existe plusieurs méthodes de jointure, qui ne diffèrent au final pas trop les unes des autres. Dans 95% des cas, voire même 99, vous aurez à faire des jointures simples, les autres sont beaucoup plus rares.

Le produit cartésien


Cela permet de sélectionner toutes les associations possibles entre 2 tables sans se soucier des liens possibles entre des attributs communs.
Il suffit de ne pas expliciter les attributs de jointure.

  1. mysql> select * from personnes, travaillent;