L'opérateur SQL EXISTS nous offre un moyen simple de récupérer des données en fonction de l'existence (ou de la non-existence) d'autres données. Plus précisément, il s'agit d'un opérateur logique qui évalue les résultats d'une sous-requête et renvoie une valeur booléenne indiquant si des lignes ont été renvoyées ou non. Bien que l'opérateur IN puisse être utilisé à peu près dans le même but, il existe quelques différences qu'il convient de connaître. Le blog d'aujourd'hui explique comment utiliser l'opérateur EXISTS à l'aide de quelques exemples et donne des conseils sur les cas où il est préférable d'utiliser EXISTS plutôt que IN.
EXISTS en action
Bien que l'opérateur EXISTS puisse être utilisé dans une instruction SELECT, UPDATE, INSERT ou DELETE, nous nous en tiendrons aux requêtes SELECT pour simplifier les choses. En tant que telle, la syntaxe que nous utiliserons ressemblera beaucoup à celle-ci :
SELECT column_name(s) FROM table_name WHERE EXISTS ( SELECT column_name(s) FROM table_name WHERE condition );
Nous exécuterons nos requêtes sur deux tables PostgreSQL - client et compte - telles que celles que l'on peut trouver dans une base de données bancaire. Les voici dans la vue Grille de Navicat for PostgreSQL :
Nous pouvons maintenant voir tous les clients qui ont un compte associé à leur customer_id à l'aide de la requête suivante :
SELECT * FROM customer C WHERE EXISTS ( SELECT * FROM account A WHERE C.customer_id = A.customer_id );
Voici la requête ci-dessus avec les résultats dans l'éditeur de requêtes de Navicat Premium :
Utilisation de NOT avec EXISTS
Inversement, si l'opérateur EXISTS est précédé du mot-clé NOT, la requête ne sélectionne que les enregistrements pour lesquels il n'existe pas de ligne correspondante dans la sous-requête. Nous pouvons utiliser NOT EXISTS pour récupérer tous les comptes orphelins, c'est-à-dire les comptes sans client associé :
SELECT * FROM account A WHERE NOT EXISTS ( SELECT * FROM customer C WHERE A.customer_id = C.customer_id );
Cela renvoie le compte du client n° 4 puisqu'il n'y a pas de client avec cet identifiant dans la table des clients.
Remplacement de EXISTS par des jointures
Les requêtes qui utilisent l'opérateur EXISTS peuvent être un peu lentes à exécuter car la sous-requête doit être exécutée pour chaque ligne de la requête externe. C'est pourquoi il est préférable d'utiliser des jointures chaque fois que cela est possible. En fait, nous pouvons réécrire la requête EXISTS ci-dessus en utilisant une jointure gauche :
SELECT C.* FROM customer C LEFT JOIN account A ON C.customer_id = A.customer_id;
Opérateurs IN et EXISTS
Bien que l'opérateur IN soit généralement utilisé pour filtrer une colonne pour une certaine liste de valeurs, il peut également être appliqué aux résultats d'une sous-requête. Voici l'équivalent de notre première requête, cette fois en utilisant IN plutôt qu'EXISTS :
SELECT * FROM customer WHERE customer_id IN (SELECT customer_id FROM account);
Notez que nous ne pouvons sélectionner que la colonne que nous voulons comparer, contrairement à SELECT *. Néanmoins, la requête IN produit les mêmes résultats :
Les deux opérateurs étant très similaires, les développeurs de bases de données ne savent pas toujours lequel utiliser. En règle générale, vous devez utiliser l'opérateur IN lorsque vous souhaitez filtrer des lignes en fonction d'une liste de valeurs spécifique. Utilisez EXISTS lorsque vous souhaitez vérifier l'existence de lignes qui répondent à certaines conditions dans une sous-requête.
Conclusion
Dans le blog d'aujourd'hui, nous avons appris à utiliser l'opérateur EXISTS et à décider s'il faut utiliser EXISTS ou IN.
Vous souhaitez essayer Navicat Premium 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.