Sous-requêtes corrélées
<<<
EXISTS et NOT EXISTS Sous-requêtes de ligne
>>>

14.1.8 Sous-sélections ( SubSELECT )
14.1 Manipulation de données : SELECT , INSERT , UPDATE , DELETE
14 Syntaxe des commandes SQL
 Manuel de Référence MySQL 4.1 : Version Française

Les sous-requêtes comme opérateur scalaire
Comparaisons avec les sous-requêtes
Sous-requêtes avec les clauses ANY , IN et SOME
Sous-requêtes avec ALL
Sous-requêtes corrélées
->EXISTS et NOT EXISTS
Sous-requêtes de ligne
Sous-requêtes dans la clause FROM
Erreurs de sous-requêtes
Optimisation des sous-requêtes
Se passer des sous-requêtes avec les premières versions de MySQL

14.1.8.6 EXISTS et NOT EXISTS

Si une sous-requête retourne absolument aucune valeur, alors la clause EXISTS <subquery> est TRUE , et la clause NOT EXISTS <subquery> est FALSE . Par exemple :


SELECT column1 FROM t1 WHERE EXISTS (SELECT * FROM t2);
Traditionnellement, une sous-requête qui EXISTS commence avec SELECT * mais elle peut commencer aussi bien avec SELECT 5 ou SELECT column1 ou n'importe quoi d'autre encore : MySQL ignore la liste de colonnes du SELECT de cette requête, ce qui fait que cela n'a pas d'importance.

Dans l'exemple ci-dessus, si la table t2 ne contient aucune ligne, même pas de ligne avec uniquement des valeurs NULL , alors la condition EXISTS est TRUE . C'est un exemple plutôt exceptionnel, car il y a presque toujours une sous-requête [NOT] EXISTS qui contiendra des corrélations. Voici des exemples plus concrets :

  • Quel type de magasin est le plus fréquent dans une ou plusieurs villes?
    
    SELECT DISTINCT store_type FROM Stores
      WHERE EXISTS (SELECT * FROM Cities_Stores
                    WHERE Cities_Stores.store_type = Stores.store_type);
  • Quel type de magasin n'est présent dans aucune villes?
    
    SELECT DISTINCT store_type FROM Stores
      WHERE NOT EXISTS (SELECT * FROM Cities_Stores
                        WHERE Cities_Stores.store_type = Stores.store_type);
  • Quel type de magasin est présent dans toutes les villes?
    
    SELECT DISTINCT store_type FROM Stores S1
      WHERE NOT EXISTS (
        SELECT * FROM Cities WHERE NOT EXISTS (
          SELECT * FROM Cities_Stores
           WHERE Cities_Stores.city = Cities.city
           AND Cities_Stores.store_type = Stores.store_type));

Le dernier exemple est une double imbrication de requête NOT EXISTS : elle possède une clause NOT EXISTS à l'intérieur de la clause NOT EXISTS . Formellement, elle répond à la question : ``Existe-t-il une ville avec un magasin qui n'est pas dans Stores?''. Mais il est plus facile de dire qu'une clause NOT EXISTS imbriquée répond à la question ``est-ce que x est vrai pour tous les y?''.

<< EXISTS et NOT EXISTS >>
Sous-requêtes corrélées Sous-sélections ( SubSELECT ) Sous-requêtes de ligne