Blog Navicat

La semi-jointure SQL Oct 15, 2024 by Robert Gravelle

La plupart des développeurs et des administrateurs de bases de données connaissent les types de jointures internes, externes, gauches et droites. Bien que ceux-ci puissent être écrits à l'aide d'ANSI SQL, il existe d'autres types de jointures basées sur des opérateurs d'algèbre relationnelle qui n'ont pas de représentation syntaxique dans SQL. Aujourd'hui, nous allons étudier l'un de ces types de jointure : la semi-jointure. La semaine prochaine, nous nous attaquerons à l'anti-jointure similaire. Pour mieux comprendre le fonctionnement de ces types de jointures, nous allons exécuter des requêtes SELECT dans Navicat Premium Lite 17 sur la dvdrental database. Il s'agit d'une base de données gratuite basée sur la base de données d'exemple MySQL Sakila.

Explication des semi-jointures

Imaginons un instant que la norme ANSI SQL prenne en charge les semi-jointures. Si c'était le cas, la syntaxe serait probablement similaire à celle de l'extension syntaxique de Cloudera Impala, à savoir LEFT SEMI JOIN et RIGHT SEMI JOIN. En gardant cela à l'esprit, voici à quoi pourrait ressembler une requête qui utilise une semi-jointure :

SELECT *
FROM actor
LEFT SEMI JOIN film_actor USING (actor_id)

La requête ci-dessus renvoie tous les acteurs qui ont joué dans des films. Le problème est que nous ne voulons pas de films dans les résultats, ni de lignes multiples pour le même acteur. Nous ne voulons que chaque acteur une fois (ou zéro fois) dans le résultat. Le mot « Semi » est d'origine latine et se traduit par « moitié » en anglais. Par conséquent, notre requête n'implémente que « la moitié de la jointure », dans ce cas, la moitié gauche. En SQL, il existe deux syntaxes alternatives que nous pouvons utiliser pour réaliser une jointure partielle : EXISTS et IN.

Semi-jointures utilisant EXISTS

Voici l'équivalent de la semi-jointure utilisant EXISTS :

SELECT *
FROM actor a
WHERE EXISTS (
  SELECT * 
  FROM film_actor fa
  WHERE a.actor_id = fa.actor_id
)

Si nous exécutons notre requête dans Navicat Premium Lite 17, nous pouvons voir qu'elle fonctionne comme prévu :

semi_join_exists (147K)

Plutôt que d'utiliser une jointure, l'opérateur EXISTS vérifie la présence d'une ou plusieurs lignes pour chaque acteur dans la table film_actor. Grâce à la clause WHERE, la plupart des bases de données seront en mesure de reconnaître que nous effectuons une SEMI JOIN plutôt qu'un prédicat EXISTS() ordinaire.

Semi-jointures utilisant IN

IN et EXISTS sont des émulations SEMI JOIN exactement équivalentes, de sorte que la requête suivante produira exactement les mêmes résultats dans la plupart des bases de données que la requête EXISTS précédente :

SELECT *
FROM actor
WHERE actor_id IN (
  SELECT actor_id FROM film_actor
)

Voici à nouveau la requête ci-dessus et les résultats dans Navicat Premium Lite 17:

semi_join_in (157K)

EXISTS est considéré comme la syntaxe la plus puissante (bien qu'un peu plus verbeuse).

Conclusion

Dans le blog d'aujourd'hui, nous avons appris à émuler une semi-jointure en utilisant la syntaxe ANSI SQL. En plus d'être la solution optimale en termes de « correction », l'utilisation d'une "SEMI" JOIN plutôt qu'une INNER JOIN présente également certains avantages en termes de performances, car la base de données peut arrêter de rechercher des correspondances dès qu'elle en a trouvé une.

Vous souhaitez essayer Navicat Premium Lite 17 ? Vous pouvez le télécharger pour un essai GRATUIT entièrement fonctionnel de 14 jours. Il est disponible pour les systèmes d'exploitation Windows, macOS et Linux.

Partager
Archives du blog