Cours PHP - leçon 3.6 - Travail avec la base de données MySQL. Types d’opérateurs JOIN.
En MySQL, il existe plusieurs façons d'effectuer des sélections avec JOIN. Nous allons essayer de couvrir tous ces types de requêtes. Voici la liste des requêtes impliquant JOIN :
- INNER JOIN
- LEFT JOIN
- LEFT JOIN sans intersections avec la table de droite
- RIGHT JOIN
- RIGHT JOIN sans intersections avec la table de gauche
- FULL OUTER JOIN
- FULL OUTER JOIN où la table de gauche ou de droite est vide
Voici une illustration de ces types de JOIN :
Je joindrai à cet article les fichiers de notre site, dont join.php où j’afficherai tous les enregistrements avec différents opérateurs JOIN.
INNER JOIN
Commençons par l’opérateur INNER JOIN, car c’est celui qui s’applique par défaut si vous écrivez simplement JOIN dans une requête. Cet opérateur sélectionne toutes les entrées des deux tables où la condition après ON est vraie. Nous avons deux tables : Messages et Files :
Table Messages :
mid | bodytext | fid |
1 | Test | NULL |
2 | Hi | 2 |
3 | Hello | NULL |
Table Files :
fid | path |
1 | /files/1.png |
2 | /files/2.png |
3 | /files/3.png |
La requête JOIN :
SELECT * FROM Messages INNER JOIN Files ON Messages.fid=Files.fid
Le résultat affichera :
mid | bodytext | fid | path |
2 | Hi | 2 | /files/2.png |
Autrement dit, seules les lignes où fid correspond sont affichées.
LEFT JOIN
Avec LEFT JOIN, on affiche toutes les lignes de la table de gauche (Messages ici), même si les valeurs fid n’ont pas de correspondance dans Files.
Table Messages :
mid | bodytext | fid |
1 | Test | 2 |
2 | Hi | NULL |
3 | Hello | 3 |
Table Files :
fid | path |
1 | /files/1.png |
2 | /files/2.png |
3 | /files/3.png |
Requête LEFT JOIN :
SELECT * FROM Messages LEFT JOIN Files ON Messages.fid=Files.fid
Résultat :
mid | bodytext | fid | path |
1 | Test | 2 | /files/2.png |
2 | Hi | NULL | NULL |
3 | Hello | 3 | /files/3.png |
LEFT JOIN est utile pour afficher tous les messages, qu’ils aient un fichier joint ou pas, la vérification se faisant ensuite en PHP.
LEFT JOIN sans intersections avec la table de droite
Cette requête affiche toutes les lignes de la table de gauche sauf celles dont fid correspondent à la table de droite.
Requête :
SELECT * FROM Messages LEFT JOIN Files ON Messages.fid=Files.fid WHERE Files.fid IS NULL
Résultat :
mid | bodytext | fid | path |
2 | Hi | NULL | NULL |
Utile pour afficher toutes les entrées sans fichiers attachés.
RIGHT JOIN
RIGHT JOIN affiche toutes les lignes de la table de droite, avec les données correspondantes de la table de gauche s’il y a intersection.
Requête :
SELECT * FROM Messages RIGHT JOIN Files ON Messages.fid=Files.fid
Résultat :
mid | bodytext | fid | path |
NULL | NULL | 1 | /files/1.png |
1 | Test | 2 | /files/2.png |
3 | Hello | 3 | /files/3.png |
RIGHT JOIN est utilisé pour afficher tous les fichiers joints, qu’ils soient utilisés ou non.
RIGHT JOIN sans intersections
Affiche toutes les lignes de la table de droite sans correspondance dans la table de gauche.
SELECT * FROM Messages RIGHT JOIN Files ON Messages.fid=Files.fid WHERE Messages.fid IS NULL
Résultat :
mid | bodytext | fid | path |
NULL | NULL | 1 | /files/1.png |
Utile pour afficher les fichiers non utilisés, non attachés à un message.
FULL OUTER JOIN
Bien que SQL comprenne FULL OUTER JOIN, MySQL ne le supporte pas. C’est une charge lourde pour le serveur. Par exemple, avec 3 fichiers et 3 messages, la requête retourne 4 lignes. Ce n’est pas forcément une bonne idée d’écrire une requête combinant LEFT et RIGHT JOIN. Cependant, on peut émuler FULL OUTER JOIN :
SELECT * FROM Messages LEFT JOIN Files ON Messages.fid = Files.fid UNION SELECT * FROM Messages RIGHT JOIN Files ON Messages.fid = Files.fid
Cette requête utilise UNION pour combiner LEFT et RIGHT JOIN.
Résultat :
mid | bodytext | fid | path |
1 | Test | 2 | /files/2.png |
2 | Hi | NULL | NULL |
3 | Hello | 3 | /files/3.png |
NULL | NULL | 1 | /files/1.png |
Il est difficile de dire à quoi sert un FULL OUTER JOIN, mais puisqu’il existe en SQL, il sera peut-être utile plus tard.
FULL OUTER JOIN sans intersections
Un type de JOIN encore plus rare : FULL OUTER JOIN sans intersections. Cette requête retourne les fichiers non utilisés et les messages sans fichiers. Comme précédemment, MySQL ne supporte pas cette requête, on l’émule avec :
SELECT * FROM Messages LEFT JOIN Files ON Messages.fid = Files.fid WHERE Files.fid IS NULL UNION SELECT * FROM Messages RIGHT JOIN Files ON Messages.fid = Files.fid WHERE Messages.fid IS NULL
Résultat :
mid | bodytext | fid | path |
2 | Hi | NULL | NULL |
NULL | NULL | 1 | /files/1.png |
Voilà, dans les prochains cours, nous écrirons des requêtes plus complexes impliquant plusieurs tables à la fois.