Manipulation de données : jointures
mises à jour : 22.08.2004, 09.08.2005
Nous supposons deux tables, l'une stockant des employés et qui s'appelle simplement `employes`, et l'autre des services, et qui s'appele `services`. C'est très compliqué, n'est-ce pas ! (^_^)
Nous lui donnons le schéma
SQL simplifié ci-dessous. Les champs soulignés sont les clés primaires, et ceux précédes d'un dièse sont des clés étrangères faisant référence à la clé primaire d'une autre table/entité.
`employes` ( employe_id, nom, prenom, age, salaire, #ref_service, fonction, date_embauche, #superieur );
`services` ( service_id, nom_service, ville );
« ref_service » dans `employes` est clé étrangère de « service_id » de `services`.
« superieur » dans `employes` est clé étrangère de « employe_id » de `employes`. Nous verrons plus loin de quoi il s'agit exactement...
II.1 Équi-jointure (parfois 'relations entre tables choisies')
Maintenant, nous voulons choisir les noms des personnes ainsi que le nom du service dans lequel elles travaillent. Nous allons donc spontanément écrire la requete suivante :
SELECT nom, nom_service FROM employes, services;
Le problème, c'est que la requête ci-dessus est
complètement fausse ! On choisit peut-être le nom de la personne et du service, mais on ne choisit pas le nom du service pour lequel travaille la personne.
Il s'opère, avec cette belle requête, un
produit cartésien entre les 2 tables choisies, c'est-à dire création de l'ensemble des combinaisons possibles entre les deux tables...
Il faut faire ce que l'on appelle une
jointure entre les tables (
on parle parfois de liaison), qui sert à rappeller que la clé étrangère de la table A fait référence à la clé primaire de la table B. Dans notre cas, la relation employé / service se fait en indiquant dans la table des employés le numéro identifiant le service, « ref_service ». On doit donc mettre dans la requête :
SELECT nom, nom_service FROM employes, services WHERE services.service_id = employes.ref_service;
Le préfixage (
càd le 'table.'
dans la cha�ne 'table.champ') est facultatif, mais si le champ « ref_service » se serait appellé « id_service », comme la clé de la table `services`, cela serait devenu obligatoire !
On peut néamoins utiliser des synonymes locaux pour les noms de tables, ca permet de gagner de la place dans le cas de noms de tables qui soient long :
SELECT nom, nom_service FROM employes e, services s WHERE s.service_id = e.ref_service;
Attention ! les synonymes locaux ne peuvent pas être des numéros seuls ou ne peuvent pas commencer par un numéro, mais par contre, une combinaison lettre(s) puis numéro(s) peut fonctionner : E1, N23... Et ils sont dans la plupart des cas sensibles à la casse (majuscules / minuscules), faites-y bien attention.
Attention, IMPORTANT !! vous avez toujours une jointure de moins que de tables dans la clause « FROM ». Deux tables = une jointure, trois tables = deux jointures, ..., 10 tables = 9 jointures, etc...
II.2 Équi-jointure réflexive (ou 'auto-jointure')
Plus rare, l'auto-jointure se fait sur deux tables, mais qui sont les mêmes !
Exemple avec notre table d'employés, chacun d'entre eux à son chef, que l'on affecte par son numéro identifiant et que l'on stocke dans « superieur ». On obtient alors la requête :
SELECT e1.nom, e2.nom FROM employes e1, employes e2 WHERE e1.employe_id = e2.superieur;
Le recours à des synonymes locaux est ici indispensable, puisque les tables sont les mêmes.
Pour continuer :
>> Les opérateurs.