Bases des bases de données
À partir d'une table Client(IdClient, Nom) et d'une table Commande(IdCommande, IdClient, Montant), on veut obtenir le nom des clients qui n'ont jamais passé de commande. Quelle instruction SQL est correcte ?
- ASELECT Nom FROM Client WHERE EXISTS (SELECT * FROM Commande WHERE Commande.IdClient = Client.IdClient)
- BSELECT Nom FROM Client WHERE NOT EXISTS (SELECT * FROM Commande)
- CSELECT Nom FROM Client WHERE NOT EXISTS (SELECT * FROM Commande WHERE Commande.IdClient = Client.IdClient)
Afficher la réponse et l'explication
Réponse : C. SELECT Nom FROM Client WHERE NOT EXISTS (SELECT * FROM Commande WHERE Commande.IdClient = Client.IdClient)
EXISTS est un prédicat qui est vrai si la sous-requête entre parenthèses renvoie au moins une ligne, et faux si elle n'en renvoie aucune ; NOT EXISTS est l'inverse. Utiliser une colonne de la table externe à l'intérieur de la sous-requête, comme dans Commande.IdClient = Client.IdClient, en fait une sous-requête corrélée qui vérifie, pour chaque ligne de la table externe Client, si ce client a des commandes. Combiné à NOT EXISTS, seuls les clients sans aucune commande restent. Avec EXISTS, on obtient l'inverse : les clients qui ont déjà commandé. Sans condition reliant la sous-requête au client, la sous-requête renvoie toujours des lignes dès que la table Commande en contient au moins une ; NOT EXISTS est alors toujours faux et le résultat compte 0 ligne. On peut aussi obtenir le même résultat avec un LEFT OUTER JOIN, en sélectionnant les lignes où les colonnes côté Commande sont NULL.
Continuer : 9 autres questions sur Bases des bases de données