Bienvenue Prénom - Déconnexion

Mot de passe oublié ?Accès membres : merci de vous identifier

BOURSE

RUBRIQUES

 
 TUTORIELS 
Les jointures en langage SQL
Savoir interroger une table, c'est bien, obtenir une sélection de tuples à partir de deux tables, c'est encore mieux : introduction aux jointures.  (18 décembre 2001)
 

Pages 1 | 2

Quelques types de jointures

La jointure la plus simple est appelée "jointure d'égalité", c'est sans doute la plus employée. Sur nos tables, cela donne par exemple :

SELECT nom_formation, nom_expert
FROM formations, experts
WHERE formations.id_expert = experts.id_expert


On obtient :

nom_formation
nom_expert
C#
Lars
Cold Fusion
Kirk
Web Services
Peter
Php
Jessie
ADO.NET
Peter

Nous avons "croisé" les deux tables pour ne retenir que les enregistrements pour lesquels l'identifiant d'un expert correspond à une formation. Deux formateurs n'apparaissent pas ici (James et Jason), ils ne sont attribués à aucune formation.

Vu la taille de nos deux tables, il n'est effectivement pas compliqué de déterminer quels experts sont actuellement attribués à une formation, et ceux qui ne le sont pas, mais comment formaliser la chose d'un point de vue SQL ?

Les clauses NOT IN / IN associées à une requête imbriquée permettent de manière intuitive d'y répondre :

SELECT e.id_expert
FROM experts e
WHERE e.id_expert NOT IN (SELECT id_expert
                                                         FROM formations)


On obtient dans ce cas les "id_expert" 1 et 4, correspondant aux experts non attribués. Hélas MySQL n'accepte pas encore les requêtes imbriquées... Comment faire ? Il faut passer par une jointure externe.

Avant d'appliquer ce type de jointures à notre problème, voyons comment celles-ci fonctionnent de manière générale.

Nous utiliserons les commandes LEFT JOIN et RIGHT JOIN pour illustrer nos propos (jointure externe gauche, et droite).

Une jointure à base de LEFT JOIN permet dans un cas simple comme le nôtre (deux tables), de récupérer à la fois l'intégralité de la première table mais aussi des enregistrements de la seconde table, à condition que ces derniers correspondent à une valeur existante dans la première table.

Un exemple devrait clarifier ce principe :

SELECT id_formation, nom_formation, nom_expert
FROM formations
LEFT JOIN experts ON formations.id_expert = experts.id_expert

On obtient :

id_formation
nom_formation
nom_expert
1
C#
Lars
2
Cold Fusion
Kirk
3
Web Services
Peter
4
Php
Jessie
5
ADO.NET
Peter
6
XML
NULL

Dans cette requête la première table, "formations", est ici reprise en intégralité. Par contre, seuls les experts (seconde table) reliés à ces formations sont récupérés. La valeur "NULL" (pas de donnée) est retournée pour la formation "XML", qui n'a pas encore trouvée son expert, nous verrons comment exploiter cette propriété un peu plus tard.

Si nous inversons l'ordre des tables de ce LEFT JOIN...

SELECT id_formation, nom_formation, nom_expert
FROM experts
LEFT JOIN formations ON formations.id_expert = experts.id_expert


... C'est cette fois la première table (donc "experts" ici) qui est reprise en intégralité, on obtient :

id_formation
nom_formation
nom_expert
NULL
NULL
James
1
C#
Lars
2
Cold Fusion
Kirk
NULL
NULL
Jason
3
Web Services
Peter
5
ADO.NET
Peter
4
Php
Jessie

L'intérêt d'une telle requête est de ramener tous les experts, d'attribuer à ceux qui ont en une, leur formation, pour les autres, la valeur NULL prend le relais.

Justement, avant de passer à l'exploitation de ce champ "NULL", regardons simplement un exemple de jointure externe droite. Rien de nouveau par rapport aux jointures externes gauches, la syntaxe change, le résultat reste le même ici :

SELECT id_formation, nom_formation, nom_expert
FROM formations
RIGHT JOIN experts ON formations.id_expert = experts.id_expert


On obtient exactement le même résultat qu'avec la requête "LEFT JOIN" précédente.
Lors du "RIGHT JOIN" ça n'est plus la première table de l'expression qui est conservée, mais la seconde (ici "experts").

A noter que nous aurions pu utiliser, à la fois pour le LEFT JOIN et le RIGHT JOIN la syntaxe USING :

SELECT id_formation, nom_formation, nom_expert
FROM formations
RIGHT JOIN experts USING (id_expert)


Maintenant que le fonctionnement d'une jointure externe LEFT JOIN de base est compris, voyons comment trouver la solution de notre problème : détecter l'expert non attribué à une formation... Nous allons exploiter le fait qu'un "NULL" soit retourné lorsque l'expert n'a pas "de correspondance" avec l'une des formations existantes :

Procédons par ordre.
Avec :

SELECT nom_expert, id_formation
FROM experts
LEFT JOIN formations USING (id_expert)

... Nous obtenons :

nom_expert
id_formation
James
NULL
Lars
1
Kirk
2
Jason
NULL
Peter
3
Peter
5
Jessie
4

Il ne reste qu'à implémenter à notre requête une restriction portant sur le NULL :

SELECT nom_expert
FROM experts
LEFT JOIN formations USING (id_expert)
WHERE id_formation IS NULL


Nous obtenons nos deux "coupables" :

nom_expert
James
Jason


Ainsi s'achève cette introduction aux jointures, il en existe d'autres, bien plus complexes. Selon le SGBD sur lequel vous effectuez ces jointures, la syntaxe change. En effet, bien que s'appuyant sur des normes (SQL-92), les différents SGBD implémentent les jointures à leur manière, ce qui rend le code difficilement portable d'un SGBD à l'autre pour ce type d'opérations.

Si vous souhaitez reproduire chez vous les requêtes présentées ici, sous MySQL, voici de quoi créer tables et données.

Pages 1 | 2

 
[ Arnaud GadalJDNet
 
Accueil | Haut de page
 
 

 

A VOIR EGALEMENT