|
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" :
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
|