Tu connais sûrement LEFT JOIN, RIGHT JOIN, INNER JOIN et FULL OUTER JOIN, non ?

LE RAPPEL
Les 4 joins que tout le monde connaît

Ce visuel les résume très bien :

Infographie « Top 4 des jointures SQL » : inner join, left join, right join et full outer join, chacun avec son diagramme de Venn, une requête SELECT type et des tables d'exemple (users avec Noah, Elio et Manon, et orders).

En deux mots :

  • INNER JOIN : retourne uniquement les lignes qui ont une correspondance dans les deux tables.

  • LEFT JOIN : retourne toutes les lignes de la table de gauche et les lignes correspondantes de la table de droite. Les lignes de gauche sans correspondance ont des valeurs nulles côté droit.

  • RIGHT JOIN : retourne toutes les lignes de la table de droite et les lignes correspondantes de la table de gauche. Les lignes de droite sans correspondance ont des valeurs nulles côté gauche.

  • FULL OUTER JOIN : retourne toutes les lignes dès qu'il y a une correspondance d'un côté ou de l'autre. Les lignes sans correspondance contiennent des valeurs nulles.

Ces quatre-là sont les types de joins SQL les plus courants.

Mais il y en a d'autres.

Aujourd'hui, je te présente trois d'entre eux, que je trouve bien pratiques à l'occasion :

  • SEMI JOIN

  • ANTI JOIN

  • NATURAL JOIN

On y va !

SEMI JOIN
Semi Join : vérifier qu'une correspondance existe

Le SEMI JOIN ressemble beaucoup à un LEFT JOIN, mais avec trois différences notables :

1. Si la condition de jointure entre deux lignes est vraie (TRUE), seules les colonnes de la table de gauche sont retournées. Le LEFT JOIN, lui, retourne les colonnes des deux tables.

Schéma d'un semi join SQL : quand la condition de jointure est vraie entre une ligne de gauche et une ligne de droite, seules les colonnes de la ligne de gauche sont retournées.

2. Si une ligne de la table de gauche n'a aucune correspondance, elle n'est pas retournée. Avec un LEFT JOIN, toutes les lignes de gauche sont retournées, qu'elles aient une correspondance ou non.

Schéma d'un semi join SQL : une ligne de la table de gauche sans correspondance dans la table de droite n'est pas retournée.

3. Si une ligne de la table de gauche a plusieurs correspondances, une seule entrée est retournée. Avec un LEFT JOIN, chaque correspondance est retournée, donc la ligne apparaît autant de fois qu'il y a de correspondances.

Par exemple, imaginons qu'on a les deux tables suivantes :

Deux tables : users avec 123 Noah, 124 Elio et 125 Manon, et orders avec les commandes 333 (User_ID 123), 222 (User_ID 125) et 111 (User_ID 126). Les lignes qui ont une correspondance sont surlignées : Noah et la commande 333 en bleu, Manon et la commande 222 en orange.

En exécutant un SEMI JOIN, on obtient ce résultat :

Requête SQL « select * from users U SEMI JOIN orders O ON (U.User_ID = O.User_ID); » et son résultat : deux lignes de la table users, 123 Noah et 125 Manon.

Comme on le voit, contrairement au LEFT JOIN :

  • il ne retourne que les colonnes de la table de gauche ;

  • il ne retourne que les lignes de gauche qui ont une correspondance.

Si un enregistrement a plusieurs correspondances, comme ici :

Tables users (123 Noah, 124 Elio, 125 Manon) et orders, où Noah (User_ID 123) a deux commandes, 333 et 222, surlignées en bleu, et où la commande 111 appartient à l'utilisateur 126.

…on remarque que le SEMI JOIN ne retourne qu'un seul enregistrement de la table de gauche :

Même requête SEMI JOIN sur les tables aux correspondances multiples : le résultat ne contient qu'une seule ligne, 123 Noah, malgré ses deux commandes.

Je trouve le SEMI JOIN particulièrement utile quand je veux seulement savoir si des enregistrements existent dans une autre table. Le LEFT JOIN renvoie des doublons qui n'ont aucun intérêt à ce stade.

ANTI JOIN
Anti Join : ce que le semi join écarte

Les lignes de la table de gauche écartées par le SEMI JOIN sont justement le résultat d'un ANTI JOIN.

Autrement dit :

Équation « [SEMI JOIN] + [ANTI JOIN] = [TABLE DE GAUCHE] » : le semi join et l'anti join réunis redonnent toutes les lignes de la table de gauche.

Reprenons les tables orders et users de tout à l'heure (celles où il n'y avait pas de correspondances multiples) :

Deux tables : users avec 123 Noah, 124 Elio et 125 Manon, et orders avec les commandes 333 (User_ID 123), 222 (User_ID 125) et 111 (User_ID 126). Les lignes qui ont une correspondance sont surlignées : Noah et la commande 333 en bleu, Manon et la commande 222 en orange.

En exécutant un ANTI JOIN, on obtient ce résultat :

Requête SQL « select * from users U ANTI JOIN orders O ON (U.User_ID = O.User_ID); » et son résultat : une seule ligne de la table users, 124 Elio, qui n'a aucune commande.

Les résultats du SEMI JOIN et de l'ANTI JOIN montrent bien que :

Illustration de « [SEMI JOIN] + [ANTI JOIN] = [TABLE DE GAUCHE] » : le résultat du semi join (123 Noah et 125 Manon) plus celui de l'anti join (124 Elio) redonne la table users complète (Noah, Elio, Manon).

Bien sûr, l'ordre peut être différent. Quand je dis « [SEMI JOIN] + [ANTI JOIN] = [TABLE DE GAUCHE] », je parle de l'ensemble des enregistrements.

Je trouve l'ANTI JOIN particulièrement utile quand je veux savoir quels enregistrements n'existent pas dans une autre table.

NATURAL JOIN
Natural Join : une jointure sans condition explicite

Celui-ci ressemble à l'INNER JOIN, mais il n'y a pas besoin de spécifier la condition de jointure.

À la place, il considère automatiquement une condition de jointure sur TOUTES les colonnes qui portent le même nom dans les deux tables.

Reprenons les tables users et orders :

Deux tables : users avec 123 Noah, 124 Elio et 125 Manon, et orders avec les commandes 333 (User_ID 123), 222 (User_ID 125) et 111 (User_ID 126). Les lignes qui ont une correspondance sont surlignées : Noah et la commande 333 en bleu, Manon et la commande 222 en orange.

Ici, la colonne User_ID est présente dans les deux tables.

En exécutant un NATURAL JOIN, on obtient ce résultat :

Requête SQL « select * from users U NATURAL JOIN orders O; » et son résultat : 123 Noah 333 et 125 Manon 222, avec les colonnes User_ID, User_Name et Order_ID.

Comme on le voit, le résultat est semblable à celui d'un INNER JOIN. En revanche, on n'a pas eu besoin de spécifier explicitement la condition de jointure, ce qui peut, il faut l'admettre, être une bonne ou une mauvaise chose :

  • C'est bien, parce que ça permet d'écrire des requêtes plus concises.

  • C'est moins bien, parce qu'on n'est pas explicite sur les colonnes utilisées pour la jointure.

❝

⚠️ Attention : si les deux tables avaient aussi une autre colonne de même nom (par exemple created_at), le NATURAL JOIN l'ajouterait à la condition de jointure sans te prévenir, et le résultat pourrait changer, voire devenir vide.

Dans le doute, mieux vaut écrire la condition explicitement.

SYNTAXE
Selon ton moteur SQL

SEMI JOIN et ANTI JOIN s'écrivent tels quels dans DuckDB, que j'utilise dans le notebook. Spark SQL les écrit LEFT SEMI JOIN et LEFT ANTI JOIN. PostgreSQL, MySQL et SQL Server n'ont pas ces mots-clés : on obtient le même résultat avec WHERE EXISTS (SEMI JOIN) et WHERE NOT EXISTS (ANTI JOIN).

Quant au NATURAL JOIN, il existe dans PostgreSQL et MySQL, mais pas dans SQL Server.

Au passage, l'ANTI JOIN évite aussi le piège des valeurs NULL du NOT IN, dont je parle dans ce shot :

EN RÉSUMÉ
Trois joins pour des requêtes plus élégantes

Voilà trois types de joins SQL supplémentaires, que j'utilise de temps en temps pour écrire des requêtes concises et élégantes.

J'espère que tu as appris quelque chose de nouveau.

Le visuel ci-dessous résume bien ce qu'on a vu aujourd'hui :

Animation récapitulative des trois joins SQL sur les tables users (Noah, Elio, Manon) et orders : le semi join retourne Noah et Manon, l'anti join retourne Elio, le natural join retourne Noah 333 et Manon 222. Des flèches en pointillés animées relient les tables au résultat.
❝

À retenir : SEMI JOIN = vérifier qu'une correspondance existe, ANTI JOIN = trouver celles qui n'existent pas, NATURAL JOIN = se passer de la condition de jointure.

💻 Le code de ce shot : notebook Semi, Anti et Natural Join

Envie d'aller plus loin ? DataXp t'attend : formations et parcours pour progresser en data science, machine learning et IA.

👉 Et maintenant, à toi de jouer : Quel autre join SQL méconnu aurais-tu ajouté à cette liste ?

Commentaires

Avatar

ou participer

À lire ensuite

Des shots dans la même veine, à lire entre deux tâches.

Voir tous les shots
caret-right