EXISTS et NOT EXISTS
Vérifiez efficacement la présence de lignes associées.
EXISTS et NOT EXISTS est une leçon SQL Academy gratuite sur CoddyKit. Ceci est la leçon 2 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage SQL Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours SQL Academy comprend 4 leçons au total.
Qu'est-ce que EXISTS ?
L'opérateur EXISTS vérifie si une sous-requête renvoie au moins une ligne. Il prend la valeur TRUE si la sous-requête produit un résultat quelconque, et FALSE si elle est vide.
Contrairement aux autres opérateurs de sous-requête qui comparent des valeurs, EXISTS s'intéresse uniquement à la présence — il n'examine pas les données réellement renvoyées par la sous-requête.
Créer les tables d'exemple
Avant d'écrire des requêtes EXISTS, créons deux tables : customers et orders. Nous les utiliserons tout au long de la leçon pour découvrir concrètement le fonctionnement de EXISTS et NOT EXISTS.
CREATE TABLE customers (
customer_id INT PRIMARY KEY,
name VARCHAR(100),
country VARCHAR(50)
);
CREATE TABLE orders (
order_id INT PRIMARY KEY,
customer_id INT,
amount DECIMAL(10,2),
order_date DATE
);
INSERT INTO customers VALUES
(1, 'Alice', 'US'),
(2, 'Bob', 'UK'),
(3, 'Charlie', 'US'),
(4, 'Diana', 'DE');
INSERT INTO orders VALUES
(101, 1, 250.00, '2024-01-10'),
(102, 1, 180.00, '2024-02-15'),
(103, 2, 95.00, '2024-03-01'),
(104, 3, 430.00, '2024-03-22');Syntaxe de base de EXISTS
La syntaxe de base de EXISTS consiste à le placer dans une clause WHERE. La sous-requête à l'intérieur de EXISTS fait généralement référence à une colonne de la requête externe — on parle alors de sous-requête corrélée.
La requête ci-dessous trouve chaque client qui a passé au moins une commande.
SELECT customer_id, name
FROM customers c
WHERE EXISTS (
SELECT 1
FROM orders o
WHERE o.customer_id = c.customer_id
);SELECT 1 dans EXISTS
Vous avez peut-être remarqué que la sous-requête utilise SELECT 1 au lieu de sélectionner une colonne réelle. C'est intentionnel : EXISTS vérifie uniquement si des lignes existent, et non ce qu'elles contiennent.
Utiliser SELECT 1 (ou même SELECT *) ne change rien au résultat, mais SELECT 1 indique clairement, à la fois au moteur de base de données et au lecteur, que les valeurs elles-mêmes n'ont pas d'importance.
-- Both of these return the same result
SELECT name FROM customers c
WHERE EXISTS (SELECT 1 FROM orders o WHERE o.customer_id = c.customer_id);
SELECT name FROM customers c
WHERE EXISTS (SELECT o.* FROM orders o WHERE o.customer_id = c.customer_id);Comment la base de données évalue EXISTS
Pour chaque ligne de la requête externe, la base de données exécute la sous-requête corrélée. Dès qu'une ligne correspondante est trouvée, le moteur arrête le parcours et marque EXISTS comme TRUE — cette évaluation par court-circuit rend EXISTS très efficace, même sur de grandes tables.
En revanche, un JOIN construit l'ensemble complet des lignes correspondantes avant le filtrage, ce qui peut être plus lent lorsque vous avez uniquement besoin de savoir si une correspondance existe.
-- EXISTS short-circuits after first match
-- Efficient even when orders table has millions of rows
SELECT name, country
FROM customers c
WHERE EXISTS (
SELECT 1
FROM orders o
WHERE o.customer_id = c.customer_id
AND o.amount > 200
);NOT EXISTS : trouver les lignes absentes
NOT EXISTS est l'inverse : il renvoie TRUE lorsque la sous-requête ne trouve aucune ligne correspondante. C'est la façon standard en SQL de répondre à des questions comme « quels clients n'ont jamais passé de commande ? »
Essayer de résoudre cela avec un JOIN classique ou NOT IN peut produire des résultats incorrects lorsque des NULL sont concernés — NOT EXISTS évite complètement ce piège.
-- Customers who have NOT placed any order
SELECT customer_id, name
FROM customers c
WHERE NOT EXISTS (
SELECT 1
FROM orders o
WHERE o.customer_id = c.customer_id
);NOT EXISTS et NOT IN avec des valeurs NULL
Un avantage crucial de NOT EXISTS par rapport à NOT IN est sa gestion sûre des NULL. Si la sous-requête utilisée par NOT IN renvoie ne serait-ce qu'un NULL, toute l'expression NOT IN devient NULL — ce qui signifie que l'absence totale de lignes est renvoyée par la requête externe.
NOT EXISTS est à l'abri de ce problème, car il évalue l'existence de lignes et non l'égalité des valeurs.
-- Dangerous: if any customer_id in orders is NULL,
-- NOT IN returns zero rows!
SELECT name FROM customers
WHERE customer_id NOT IN (SELECT customer_id FROM orders);
-- Safe: NOT EXISTS handles NULLs correctly
SELECT name FROM customers c
WHERE NOT EXISTS (
SELECT 1 FROM orders o
WHERE o.customer_id = c.customer_id
);EXISTS avec plusieurs conditions
La sous-requête à l'intérieur de EXISTS peut contenir tout SQL valide, notamment plusieurs conditions WHERE. Cela vous permet de rechercher des lignes associées très précises — par exemple, des clients ayant passé une commande supérieure à un seuil au cours d'un mois donné.
-- Customers who placed an order over 200 in March 2024
SELECT c.name, c.country
FROM customers c
WHERE EXISTS (
SELECT 1
FROM orders o
WHERE o.customer_id = c.customer_id
AND o.amount > 200
AND o.order_date >= '2024-03-01'
AND o.order_date < '2024-04-01'
);EXISTS dans DELETE et UPDATE
EXISTS ne se limite pas aux instructions SELECT. Vous pouvez l'utiliser dans UPDATE et DELETE pour modifier ou supprimer des lignes en fonction de l'existence de données associées dans une autre table.
L'exemple ci-dessous supprime les commandes appartenant à des clients d'un pays donné.
-- Delete orders placed by US customers
DELETE FROM orders o
WHERE EXISTS (
SELECT 1
FROM customers c
WHERE c.customer_id = o.customer_id
AND c.country = 'US'
);Comparer EXISTS et JOIN
EXISTS et JOIN permettent souvent de formuler la même question, mais leur comportement diffère. Un JOIN multiplie les lignes lorsqu'il existe plusieurs correspondances ; EXISTS renvoie toujours chaque ligne externe au plus une fois.
Lorsque vous avez uniquement besoin de savoir si une relation existe, et non de récupérer des données de la table associée, EXISTS est plus clair et généralement plus rapide.
-- JOIN may return duplicate customer rows if a customer has multiple orders
SELECT DISTINCT c.name
FROM customers c
JOIN orders o ON o.customer_id = c.customer_id;
-- EXISTS always returns each customer once
SELECT c.name
FROM customers c
WHERE EXISTS (
SELECT 1 FROM orders o
WHERE o.customer_id = c.customer_id
);NOT EXISTS pour les contrôles de qualité des données
NOT EXISTS est un outil puissant pour auditer la qualité des données. Vous pouvez l'utiliser pour trouver des enregistrements orphelins, des références manquantes ou des lignes qui devraient avoir des données associées mais n'en ont pas.
La requête ci-dessous détecte toutes les lignes de commandes dont customer_id ne correspond à aucune ligne de la table des clients — signe d'une intégrité référentielle rompue.
-- Find orders with no matching customer (orphaned records)
SELECT o.order_id, o.customer_id, o.amount
FROM orders o
WHERE NOT EXISTS (
SELECT 1
FROM customers c
WHERE c.customer_id = o.customer_id
);Vérification rapide
Évaluez votre compréhension de EXISTS et NOT EXISTS.
Récapitulatif de la leçon
Dans cette leçon, vous avez appris comment EXISTS et NOT EXISTS vous permettent de vérifier la présence ou l'absence de lignes associées sans comparer directement les valeurs.
Points à retenir :
- EXISTS renvoie TRUE dès que la sous-requête trouve une ligne correspondante (évaluation par court-circuit).
- NOT EXISTS renvoie TRUE lorsque la sous-requête ne trouve aucune ligne correspondante.
- Utilisez
SELECT 1dans EXISTS : les valeurs renvoyées ne sont pas pertinentes. - NOT EXISTS gère les NULL en toute sécurité ; NOT IN non — préférez NOT EXISTS lorsque des valeurs NULL peuvent apparaître.
- EXISTS fonctionne dans les instructions SELECT, UPDATE et DELETE.
- Lorsque vous avez uniquement besoin de vérifier une existence, EXISTS est souvent plus clair et plus rapide qu'un JOIN.
Questions Fréquemment Posées
La leçon « EXISTS et NOT EXISTS » est-elle gratuite ?
Oui — le texte complet de « EXISTS et NOT EXISTS » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours SQL Academy, passe à CoddyKit PRO. Le cours SQL Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « EXISTS et NOT EXISTS » ?
Vérifiez efficacement la présence de lignes associées. Tu pratiques SQL Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer SQL Academy ?
Aucune expérience préalable n'est requise. SQL Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 4.
Combien de temps prend la leçon « EXISTS et NOT EXISTS » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon SQL Academy ?
Oui. Chaque leçon SQL Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Sous-requêtes corrélées
- EXISTS et NOT EXISTS
- IN, ANY ou ALL
- Performances de EXISTS et JOIN