Les opérateurs de sous requête SQL

Une sous-requête est tout simplement une requête imbriquée dans une autre requête. Nous allons utiliser des sous requêtes lorsque nous devrons faire des opérations en plusieurs étapes, comme par exemple faire la somme des valeurs de plusieurs colonnes puis calculer la moyenne.

Dans cette leçon, nous allons découvrir de nouveaux opérateurs SQL que l’on va pouvoir utiliser spécifiquement conjointement avec des sous-requêtes.

Nous allons donc ici nous concentrer sur :

  • L’opérateur SQL EXISTS ;
  • L’opérateur SQL ANY ;
  • L’opérateur SQL ALL.

 

L’opérateur SQL EXISTS

L’opérateur SQL EXISTS va nous servir à tester l’existence d’une entrée dans une sous requête.

Cet opérateur renvoie TRUE si au moins un résultat a été trouvé. La requête principale ne s’exécutera que si la sous requête retourne au moins un résultat.

En pratique, on utilisera principalement cet opérateur pour retourner des résultats à partir d’une table seulement si une certaine condition est vérifiée dans une autre table.

Nous allons par exemple pouvoir renvoyer les informations relatives à chaque utilisateur qui a commenté sur notre site. Pour cet exemple, nous nous basons à nouveau sur les tables « users » et « comments » créées précédemment.

<!DOCTYPE html>
<html>
    <head>
        <title>Cours PHP / MySQL</title>
        <meta charset='utf-8'>
    </head>
    <body>
        <h1>Bases de données MySQL</h1>  
        <?php
            $servname = "localhost"; $dbname = "cours"; $user = "root"; $pass = "root";
            
            try{
                $dbco = new PDO("mysql:host=$servname;dbname=$dbname", $user, $pass);
                $dbco->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
                
                /*Renvoie les informations de chaque user qui a commenté*/
                $sth = $dbco->prepare("
                  SELECT * FROM users
                  WHERE EXISTS (SELECT * FROM comments WHERE comments.userId = users.id)
                ");
                
                $sth-> execute();
                
                $resultat = $sth->fetchAll(PDO::FETCH_ASSOC);
                
                echo '<pre>';
                print_r($resultat);
                echo '</pre>';
            }
                  
            catch(PDOException $e){
                echo "Erreur : " . $e->getMessage();
            }
        ?>
    </body>
</html>

 

Exemple d'utilisation de l'opérateur SQL exists dans une sous requête via PDO PHP

Ici, si notre sous-requête renvoie au moins un résultat, c’est-à-dire si la condition comments.userId = users.id (si on trouve au moins un utilisateur enregistré dans la table « users » lié à un commentaire) alors EXISTS va retourner TRUE et notre requête principale va pouvoir s’exécuter.

En d’autres mots, toutes les informations de chaque utilisateur ayant commenté seront renvoyées.

 

L’opérateur SQL ANY

L’opérateur SQL ANY va être utilisé conjointement avec une clause WHERE ou une clause HAVING dans le cas où nous utilisons une sous-requête dans notre requête.

Cet opérateur va nous permettre de comparer une valeur avec le résultat d’une sous-requête.

ANY va retourner TRUE si au moins l’une des valeurs de la sous-requête satisfait à la condition imposée et va ainsi permettre de poursuivre l’exécution de la requête principale.

Par exemple, nous allons pouvoir sélectionner les prénoms de nos utilisateurs qui ont commenté sur notre blog depuis le 18 mais 2018 à midi SI AU MOINS l’un d’entre eux a posté un commentaire depuis cette date

<!DOCTYPE html>
<html>
    <head>
        <title>Cours PHP / MySQL</title>
        <meta charset='utf-8'>
    </head>
    <body>
        <h1>Bases de données MySQL</h1>  
        <?php
            $servname = "localhost"; $dbname = "cours"; $user = "root"; $pass = "root";
            
            try{
                $dbco = new PDO("mysql:host=$servname;dbname=$dbname", $user, $pass);
                $dbco->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
                
                /*Renvoie le prenom des users qui ont écrit au moins un commentaire
                 *après le 18 mai 2018 à midi si au moins un user à écrit un
                 *commentaire depuis cette date*/
                $sth = $dbco->prepare("
                  SELECT prenom FROM users
                  WHERE id = ANY (SELECT userId FROM comments WHERE dateComment > '2018-05-18 12:00:00')
                ");
                
                $sth-> execute();
                
                $resultat = $sth->fetchAll(PDO::FETCH_ASSOC);
                
                echo '<pre>';
                print_r($resultat);
                echo '</pre>';
            }
                  
            catch(PDOException $e){
                echo "Erreur : " . $e->getMessage();
            }
        ?>
    </body>
</html>

 

Exemple d'utilisation de l'opérateur SQL any dans une sous requête via PDO PHP

Ici, si un utilisateur a posté un commentaire après le 18 mais 2018 à midi alors la sous-requête renvoie TRUE et nous allons récupérer les prénoms des utilisateurs qui ont écrit un commentaire après cette date.

 

L’opérateur SQL ALL

L’opérateur SQL ALL va également être utilisé conjointement avec une clause WHERE ou une clause HAVING dans le cas où nous utilisons une sous-requête dans notre requête.

Cependant, cette fois-ci, cet opérateur ne va retourner TRUE que si toutes les valeurs de la sous-requête satisfont à la condition posée.

Par exemple, nous allons pouvoir sélectionner les prénoms de nos utilisateurs qui ont commenté sur notre blog depuis le 18 mais 2018 à midi S’ILS ONT TOUS posté un commentaire depuis cette date

<!DOCTYPE html>
<html>
    <head>
        <title>Cours PHP / MySQL</title>
        <meta charset='utf-8'>
    </head>
    <body>
        <h1>Bases de données MySQL</h1>  
        <?php
            $servname = "localhost"; $dbname = "cours"; $user = "root"; $pass = "root";
            
            try{
                $dbco = new PDO("mysql:host=$servname;dbname=$dbname", $user, $pass);
                $dbco->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
                
                /*Renvoie le prenom des users qui ont écrit au moins un commentaire
                 *après le 18 mai 2018 à midi si chacun d'entre eux a écrit un
                 *commentaire depuis cette date*/
                $sth = $dbco->prepare("
                  SELECT prenom FROM users
                  WHERE id = ALL (SELECT userId FROM comments WHERE dateComment > '2018-05-18 12:00:00')
                ");
                
                $sth-> execute();
                
                $resultat = $sth->fetchAll(PDO::FETCH_ASSOC);
                
                echo '<pre>';
                print_r($resultat);
                echo '</pre>';
            }
                  
            catch(PDOException $e){
                echo "Erreur : " . $e->getMessage();
            }
        ?>
    </body>
</html>

 

Exemple d'utilisation de l'opérateur SQL all dans une sous requête via PDO PHP

Cette fois-ci la sous-requête ne renvoie TRUE que si tous les utilisateurs ont posté un commentaire depuis le 18 mais 2018 à midi. Si ce n’est pas le cas, elle renvoie FALSE et la requête principale (la sélection des prénoms) n’est pas exécutée et donc aucun prénom n’est sélectionné.

Laisser un commentaire