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>
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>
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>
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é.