8th Jul 2024 11 minutes de lecture L'opérateur SQL EXISTS Ignacio L. Bisso apprendre sql bases du sql Table des matières Syntaxe de l'opérateur EXISTS Exemple de base de données : Bateaux et voitures de luxe Exemples d'utilisation de l'opérateur SQL EXISTS Exemple 1 : Recherche des produits vendus Exemple 2 : Utilisation de l'opérateur NOT EXISTS Exemple 3 : Utilisation de EXISTS avec NOT EXISTS Pratiquer l'opérateur EXISTS Exercice 1 : Anciennes commandes Exercice 2 : Acheteurs de moteurs de bateaux Exercice 3 : Jamais acheté Continuez à développer vos compétences en matière d'opérateurs SQL EXISTS L'utilisation de la clause SQL EXISTS permet de créer des requêtes complexes de manière simple. Découvrez les avantages et les inconvénients de l'opérateur EXISTS dans cet article. En SQL, l'opérateur EXISTS nous aide à créer des conditions logiques dans nos requêtes. Essentiellement, il vérifie s'il y a des lignes dans une sous-requête. Nous vous montrerons la syntaxe de EXISTS, nous vous donnerons quelques exemples d'utilisation et nous vous proposerons plusieurs exercices pour vous entraîner. Si vous débutez avec SQL ou si vous avez besoin d'une remise à niveau en SQL, je vous recommande le cours SQL pour les débutants. Il comprend des sujets SQL allant des SELECT de base aux sujets complexes tels que les jointures, les agrégations et les sous-requêtes. C'est un excellent moyen d'acquérir, de rafraîchir ou d'élargir vos compétences en SQL. Syntaxe de l'opérateur EXISTS Vous connaissez probablement les opérateurs SQL tels que =, >, < et LIKE. Tous ces opérateurs peuvent être utilisés pour créer des conditions logiques qui renvoient TRUE ou FALSE. Voici quelques exemples de conditions courantes : WHERE Employee_id = 10345 WHERE Price < 1000 WHERE Name LIKE ‘John%’ Les opérateurs =, <, et LIKE comparent deux éléments ou opérandes. C'est la raison pour laquelle ils sont appelés opérateurs binaires. WHERE EXISTS ( subquery ) Voyons maintenant l'ensemble de la requête SQL pour déterminer où placer la condition EXISTS: SELECT columns FROM table1 WHERE EXISTS (SELECT columns FROM table2); L'opérateur EXISTS est utilisé pour créer des conditions booléennes afin de vérifier si une sous-requête renvoie une ou plusieurs lignes ou un ensemble vide. Lorsque sa sous-requête renvoie au moins une ligne, EXISTS renvoie TRUE. Le nombre de lignes renvoyées ou le nombre de colonnes dans la liste de la sous-requête SELECT n'a pas d'importance. Ce n'est que lorsque la sous-requête renvoie 0 ligne que EXISTS renvoie FALSE. Il est important de noter qu'aucune des lignes renvoyées par la sous-requête n'apparaît dans le résultat final. Exemple de base de données : Bateaux et voitures de luxe Examinons plusieurs exemples de requêtes basées sur la base de données d'une entreprise qui vend des voitures et des bateaux de luxe. L'entreprise garde une trace des voitures et des bateaux dans la table product, qui comporte les colonnes product_id, product_name, product_price, product_type. product_idproduct_nameproduct_priceproduct_type 100Ferrari F203000000Car 101Lamborghini AX3600000Car 102Pagani Zonda4300000Car 200VanDutch 582100000Boat 201Lamborghini B93400000Boat 202VanDutch 561800000Boat 300Boat Engine Yamei 1001000000Boat La base de données comporte également une table Client avec les colonnes client_id, client_name et country. client_idclient_namecountry 10John F.United States 11Samid A,Kuwait 12Majal H.Brunei 13Pierre B.France 14Abdul E.Kuwait Enfin, il y a la table sale avec les colonnes product_id, client_id, sale_date. (Par souci de simplicité, j'omets l'idée d'avoir une table pour les bons de commande ; dans ce type d'entreprise, un client n'achète normalement qu'un seul produit à la fois). client_idproduct_idcountry 102002020-03-05 101012024-04-05 112022023-03-05 121022021-03-07 121002023-03-05 122022024-04-09 133002022-03-05 103002020-07-19 133002023-11-25 Exemples d'utilisation de l'opérateur SQL EXISTS Exemple 1 : Recherche des produits vendus Pour le premier exemple de requête, supposons que le responsable du marketing veuille savoir quelles voitures et quels bateaux ont été vendus entre le 1er et le 15 avril 2024. C'est ce que fait la requête ci-dessous : SELECT product_name FROM product p1 WHERE EXISTS ( SELECT * FROM sale s WHERE s.product_id = p1.product_id AND s.sale_date >= ‘2024-04-01’ AND s.sale_date <= ‘2024-04-15’ ) Résultats : Product_name Lamborghini AX VanDutch 56 Il existe d'autres façons d'écrire cette requête sans utiliser l'opérateur EXISTS. Cependant, pour expliquer le fonctionnement de l'opérateur EXISTS, il s'agit d'un bon exemple d'entrée en matière. La requête principale SELECT est très simple ; elle va à la table product pour obtenir la colonne product_name. Cependant, nous ne voulons pas tous les product_names dans la table. Nous ne voulons que les produits qui renvoient TRUE pour la condition suivante : WHERE EXISTS ( SELECT * FROM sale s WHERE s.product_id = p1.product_id AND s.sale_date >= ‘2024-04-01’ AND s.sale_date <= ‘2024-04-15’ ) Si nous analysons la condition, la sous-requête renvoie tous les enregistrements de ventes pour un produit donné (p1.product_id) et pour une période spécifique (2024-04-01 à 2024-04-15). Si la sous-requête renvoie des enregistrements, alors EXISTS renverra TRUE. Si la sous-requête ne renvoie aucun enregistrement, EXISTS renverra FALSE. Notez que la sous-requête est exécutée plusieurs fois - une fois pour chaque ligne lue par la requête externe. Ces types de sous-requêtes qui sont exécutées une fois pour chaque ligne traitée dans la requête principale sont appelées "sous-requêtes corrélées" et ont leurs particularités. Si vous souhaitez approfondir ce sujet, je vous suggère l'article Correlated Subquery in SQL : Un guide pour les débutants. Exemple 2 : Utilisation de l'opérateur NOT EXISTS Supposons maintenant que le responsable veuille connaître les noms des véhicules qui n'ont pas été vendus au cours de la même période. Ce type de requête - où nous recherchons des enregistrements qui n'existent pas dans la base de données - est excellent pour l'opérateur NOT EXISTS. En effet, nous recherchons des éléments qui n'existent pas dans la base de données. La requête est la suivante : SELECT * FROM product p1 WHERE p1.product_type = ‘Car’ AND NOT EXISTS ( SELECT * FROM sale s WHERE s.product_id = p1.product_id AND s.sale_date >= ‘2024-04-01’ AND s.sale_date <= ‘2024-04-15’ ) Résultats : Product_idProduct_nameProduct_priceProduct_type 100Ferrari F203000000Car 102Pagani Zonda4300000Car Une fois que nous avons compris comment l'opérateur EXISTS fonctionne en SQL, il est très simple de comprendre NOT EXISTS; c'est l'inverse. Si EXISTS renvoie TRUE, alors NOT EXISTS renvoie FALSE et vice versa. Dans cet exemple, la requête principale comporte une clause WHERE avec deux conditions. La première condition consiste à rechercher des produits du type "véhicule". La deuxième condition utilise NOT EXISTS pour ne conserver que les produits qui n'ont pas été vendus pendant la période allant du 2024-04-01 au 2024-04-15. En d'autres termes, nous recherchons les produits pour lesquels la sous-requête renvoie un ensemble de résultats vide, c'est-à-dire pour lesquels il n'y a pas eu de ventes au cours de cette période. Dans certains cas, nous pouvons résoudre ce type de requête en utilisant NOT IN avec une sous-requête. Dans cette requête particulière, nous pouvons insérer la clause WHERE: WHERE p1.product_type = ‘Car’ AND p1.product_id NOT IN (SELECT s.product_id FROM sale s WHERE s.sale_date >= ‘2024-04-01’ AND s.sale_date <= ‘2024-04-15’ ) Cependant, il y a une différence dans la manière dont la requête est exécutée en interne dans la base de données. La condition de la sous-requête NOT IN est exécutée une fois, tandis que la condition de la sous-requête NOT EXISTS est exécutée une fois par ligne. En effet, NOT EXISTS est une sous-requête corrélée. Pour en savoir plus sur ces opérateurs, lisez les articles 5 exemples de sous-requêtes SQL et Opérateur IN SQL. Exemple 3 : Utilisation de EXISTS avec NOT EXISTS Ensuite, nous avons besoin d'une liste des clients qui n'ont pas acheté de bateau pendant l'été 2023 mais qui ont acheté un bateau pendant l'hiver précédent (c'est-à-dire de décembre 2022 à mars 2023). La requête permettant d'obtenir ce rapport est la suivante : SELECT * FROM client c1 WHERE EXISTS ( SELECT * FROM sale s1 JOIN product p1 ON p1.product_id = s1.product_id WHERE c1.client_id = s1.client_id AND p1.product_type = 'Boat' AND s1.sale_date >= '2022-12-21' AND s1.sale_date <= '2023-03-20' -- winter ) AND NOT EXISTS ( SELECT * FROM sale s2 JOIN product p1 ON p1.product_id = s2.product_id WHERE c1.client_id = s2.client_id AND p1.product_type = 'Boat' AND s2.sale_date >= '2023-6-21' AND s2.sale_date <= '2023-09-20' -- summer ) ; Résultats : client_idClient_nameCountry 11Samid A.Kuwait Après les deux exemples précédents, cet exemple ne devrait pas être trop difficile à comprendre ; il s'agit d'une combinaison des deux. L'idée est de sélectionner l'enregistrement entier (SELECT *) dans la table client puis d'utiliser EXISTS pour vérifier qu'un bateau a été acheté l'hiver dernier. Ensuite, nous utilisons NOT EXISTS pour vérifier qu'un bateau n'a pas été acheté l'été dernier. Notez que les deux sous-requêtes comportent une adresse JOIN entre les balises sale et product car nous devons utiliser les colonnes product_type et sale_date dans les conditions WHERE. À ce stade, j'aimerais clarifier un point concernant les sous-requêtes corrélées. Nous avons mentionné que les sous-requêtes corrélées sont exécutées une fois pour chaque ligne candidate. Ce fait peut avoir un impact sur les performances de l'ensemble de la requête, en particulier lorsque nous travaillons avec de grandes tables. En résumé, l'opérateur EXISTS (et les sous-requêtes corrélées) est une ressource SQL puissante pour certains types de requêtes. Cependant, nous devrions éviter les sous-requêtes corrélées si nous travaillons avec de grandes tables. Pratiquer l'opérateur EXISTS Comme pour beaucoup d'autres langages informatiques, apprendre le langage SQL en faisant des exercices est l'une des meilleures façons d'acquérir des compétences. Dans cette section, je vais donc présenter trois exercices de l'opérateur EXISTS de complexités différentes. Exercice 1 : Anciennes commandes Exercice : Le propriétaire de l'entreprise veut savoir quels produits (voitures ou bateaux) n'ont pas été commandés au cours des 365 derniers jours. Solution : SELECT p1.product_name FROM product p1 WHERE NOT EXISTS ( SELECT 1 FROM sale s WHERE s.product_id = p1.product_id AND s.sale_date >= CURRENT_DATE - 365 ); Résultats : Product_name Ferrari F20 Pagani Zonda Lamborghini B9 VanDutch 58 Explication : La requête principale utilise la table product pour obtenir la colonne product_name. La clause WHERE de cette requête est la partie clé. Elle comporte une condition NOT EXISTS qui est évaluée à TRUE pour les produits qui n'ont pas été vendus au cours de l'année écoulée. La condition s.sale_date >= CURRENT_DATE - 365 dans la sous-requête permet d'obtenir toutes les lignes de l'année dernière. Notez que la sous-requête renvoie une constante ( 1 ). En effet, l'important pour la sous-requête est le nombre de lignes qu'elle renvoie, et non le contenu des lignes renvoyées ; nous pouvons donc utiliser une colonne ou une constante telle que 1. Exercice 2 : Acheteurs de moteurs de bateaux Exercice : Notre entreprise est connue pour la fabrication d'un moteur de bateau et nous avons quelques clients qui n'achètent que ce produit. Le service marketing souhaite identifier les clients qui n'achètent que des moteurs de bateaux afin de pouvoir les cibler dans une campagne de marketing. Solution : SELECT * FROM client c1 WHERE EXISTS ( SELECT * FROM sale s1 -- they buy boat engines JOIN product p1 ON p1.product_id = s1.product_id WHERE c1.client_id = s1.client_id AND p1.product_name = 'Boat engine' ) AND NOT EXISTS ( SELECT * FROM sale s2 -- they never buy other product JOIN product p2 ON p2.product_id = s2.product_id WHERE c1.client_id = s2.client_id AND p2.product_name <> 'Boat engine' ); Résultats : client_idClient_nameCountry 13Pierre B.France 14Abdul E.Kuwait Explication : Cet exercice comporte une clause WHERE avec deux conditions. La première condition utilise un opérateur EXISTS pour vérifier que le client sélectionné par la requête externe a acheté un moteur de bateau. La seconde condition WHERE utilise NOT EXISTS pour vérifier que le même client (le client sélectionné par la requête externe) n'a jamais acheté un autre type de produit. Si vous souhaitez explorer d'autres exercices sur les sous-requêtes, je vous recommande l'article Pratique des sous-requêtes SQL : 15 exercices avec solutions. Exercice 3 : Jamais acheté Exercice : Le propriétaire de l'entreprise veut un rapport " Jamais acheté" . Le rapport ne doit comporter que deux colonnes : client_name et product_name. Le contenu du rapport doit être le complément de la table sale tableau. En d'autres termes, si un client n'a jamais acheté un produit, la paire formée par ce client_name et ce product_name doit figurer dans le rapport. Solution : Il existe deux approches pour résoudre cet exercice : En utilisant NOT EXISTS. En utilisant l'opérateur d'ensemble EXCEPT (ou MINUS). Nous montrerons les deux approches. Solution en utilisant NOT EXISTS: SELECT c1.client_name, p1.product_name FROM client c1, product p1 WHERE NOT EXISTS ( SELECT 1 FROM sale s WHERE c1.client_id = s.client_id AND p1.product_id = s.product_id ) Résultats partiels de la requête : Client_nameProduct_name John F.Ferrari F20 John F.Pagani Zonda John F.Lamborghini B9 John F.VanDutch 56 Samid A.Lamborghini AX Samid A.Pagani Zonda Samid A.VanDutch 56 Samid A.Lamborghini B9 Samid A.Boat Engine Yamei 100 Samid A.Ferrari F20 Explication : Le premier point à comprendre est le résultat de cette partie de la requête : SELECT c1.client_name, p1.product_name FROM client c1, product p1 Comme nous ne joignons pas correctement les tables client et productle résultat est un produit cartésien - un ensemble de toutes les paires <client_name, product_name> possibles. Une fois que nous avons toutes les paires possibles, nous procédons à l'élimination de ces paires dans le tableau à l'aide de l'opérateur . sale à l'aide de l'opérateur NOT EXISTS. Solution en utilisant EXCEPT: SELECT c1.client_name, p1.product_name FROM client c1, product p1 EXCEPT SELECT client_name, product_name FROM sale s JOIN product p ON p.product_id = s.product_id JOIN client c ON c.client_id = s.client_id Explication : La première partie de cette approche est similaire à la solution précédente ; nous créons toutes les paires client-produit possibles. Ensuite, à l'aide de l'opérateur EXCEPT, nous supprimons les paires qui se trouvent dans le tableau. sale tableau. Nous obtenons ainsi les paires que nous recherchons. Voici la différence : Dans la deuxième partie de EXCEPT, nous devons JOIN le tableau sale à l'aide de l'opérateur product et client tables. Continuez à développer vos compétences en matière d'opérateurs SQL EXISTS Dans cet article, nous avons abordé les opérateurs EXISTS et NOT EXISTS à l'aide de plusieurs exemples. Nous avons également expliqué les avantages et les inconvénients des sous-requêtes corrélées. Pour les lecteurs qui souhaitent améliorer leurs compétences en SQL, je recommande la piste La pratique du SQL piste. Vous y trouverez des centaines d'exercices sur des sujets SQL comme les JOIN, GROUP BY, HAVING, les sous-requêtes et même l'opérateur EXISTS. Si vous débutez avec SQL ou si vous avez besoin d'une remise à niveau, je vous recommande notre cours de SQL pour les débutants cours. Lorsque vous améliorez vos compétences en SQL, vous investissez en vous ! Tags: apprendre sql bases du sql