-
La table Clients : Chaque ligne décrit un client. Les colonnes décrivent successivement le numero du client, son nom et prenom, son adresse avec rue, codePostal, ville, son telephone, sa categorie et l’état de son compte. L’identifiant primaire est constitué de numero. Les colonnes telephone et categorie sont facultatives.
-
La table Produits : chaque ligne décrit un produit ; les colonnes décrivent successivement le numero du produit, son nom, son prix unitaire et la quantité restante en stock. numero est l’identifiant primaire.
-
La table Commandes : chaque ligne décrit une commande passée par un client ; les colonnes décrivent successivement le numero de la commande, le numeroClient du client qui a passé la commande, la dateCommande de la commande et le statut de la commande. L’identifiant primaire est constitué de numero. numeroClient est une clé étrangère vers la table Clients.
-
La table Details : chaque ligne représente un détail d’une commande ; les colonnes décrivent successivement le numero de la commande à laquelle le détail appartient, le numero du produit commandé et la quantité commandée. L’identifiant primaire est constitué de numeroCommande et numeroProduit. numeroCommande et numeroProduit sont en outre chacune une clé étrangère respectivement vers les tables Commandes et Produits.
Questions
Formulez les requêtes suivantes en SQL. Vous pouvez d’abord utiliser l’algèbre relationnelle pour les formuler puis les convertir en SQL.
Requêtes SQL pour le schéma de base de données
-- 1. Liste des produits en stockSELECT numero, nom, prix, stockFROM ProduitsWHERE stock > 0;
-- 2. Liste des villes où il existe au moins un clientSELECT DISTINCT villeFROM Clients;
-- 3. Clients de catégorie B2 n'habitant pas à ParisSELECT numero, nom, villeFROM ClientsWHERE categorie = 'B2'AND ville <> 'Paris';
-- 4. Produits en stock dont le prix est supérieur à 100SELECT numero, nom, prix, stockFROM ProduitsWHERE stock > 0AND prix > 100;
-- 5. Clients de Paris ou Grenoble avec un compte positifSELECT numero, nom, compteFROM ClientsWHERE (ville = 'Paris' OR ville = 'Grenoble')AND compte > 0;
-- 6. Catégories de clients à ParisSELECT DISTINCT categorieFROM ClientsWHERE ville = 'Paris';
-- 7. Clients dont le nom précède alphabétiquement la villeSELECT numero, nom, villeFROM ClientsWHERE nom < ville;
-- 8. Statistiques des comptes des clientsSELECT SUM(compte) AS total, MIN(compte) AS minimum, AVG(compte) AS moyenne, MAX(compte) AS maximumFROM Clients;
-- 9. Numéros des clients qui commandent le produit 1SELECT DISTINCT numeroClientFROM CommandesWHERE numero IN ( SELECT numeroCommande FROM Details WHERE numeroProduit = 1);
-- Version JOINSELECT DISTINCT numeroClientFROM CommandesJOIN Details ON Commandes.numero = Details.numeroCommandeWHERE numeroProduit = 1;
-- 10. Villes des clients qui commandent le produit 1SELECT C.ville FROM Clients C WHERE C.numero IN ( SELECT COM.numeroClient FROM Commandes COM WHERE COM.numero IN ( SELECT D.numeroCommande FROM Details D WHERE D.numeroProduit = 1 ));
-- Version JOINSELECT DISTINCT villeFROM ClientsJOIN Commandes ON Clients.numero = Commandes.numeroClientJOIN Details ON Commandes.numero = Details.numeroCommandeWHERE numeroProduit = 1;
-- 11. Clients de Grenoble qui n'ont pas passé de commandesSELECT numero, nomFROM ClientsWHERE ville = 'Grenoble'AND numero NOT IN ( SELECT numeroClient FROM Commandes);
-- 12. Produits contenant la lettre `t` dans leur nom et commandésSELECT DISTINCT numero, nomFROM ProduitsWHERE nom LIKE '%t%'AND numero IN ( SELECT numeroProduit FROM Details);
-- Version JOINSELECT DISTINCT Produits.numero, Produits.nomFROM ProduitsJOIN Details ON Produits.numero = Details.numeroProduitWHERE Produits.nom LIKE '%t%';
-- 13. Requêtes sur les clients
-- 13.1 Habitants de Lille ou GrenobleSELECT * FROM Clients WHERE ville = 'Lille' OR ville = 'Grenoble';
-- 13.2 Habitants de Lille et non GrenobleSELECT * FROM Clients WHERE ville = 'Lille' AND ville <> 'Grenoble';
-- 13.3 Habitants de Lille ou n'habitant pas GrenobleSELECT * FROM Clients WHERE ville = 'Lille' OR ville <> 'Grenoble';
-- 13.4 Ni Lille ni GrenobleSELECT * FROM Clients WHERE ville <> 'Lille' AND ville <> 'Grenoble';
-- 13.5 N'habitant pas à Lille ou GrenobleSELECT * FROM Clients WHERE ville <> 'Lille' OR ville <> 'Grenoble';
-- 13.6 Catégorie B2 habitant à GrenobleSELECT * FROM Clients WHERE categorie = 'B2' AND ville = 'Grenoble';
-- 13.7 Catégorie B2 ou habitant à GrenobleSELECT * FROM Clients WHERE categorie = 'B2' OR ville = 'Grenoble';
-- 13.8 Catégorie B2 n'habitant pas à GrenobleSELECT * FROM Clients WHERE categorie = 'B2' AND ville <> 'Grenoble';
-- 13.9 Pas sélectionné dans la question précédenteSELECT * FROM Clients WHERE numero NOT IN ( SELECT numero FROM Clients WHERE categorie = 'B2' AND ville <> 'Grenoble');
-- 13.10 Catégorie B1 ou B2, ou habitant à Lille ou GrenobleSELECT * FROM Clients WHERE (categorie = 'B1' OR categorie = 'B2') OR (ville = 'Lille' OR ville = 'Grenoble');
-- 13.11 Catégorie B1 ou B2, ou habitant à Lille ou Grenoble, mais pas les deuxSELECT * FROM Clients WHERE((categorie = 'B1' OR categorie = 'B2') AND (ville != 'Lille' AND ville != 'Grenoble'))OR((categorie = 'B1' AND categorie = 'B2') AND (ville = 'Lille' OR ville = 'Grenoble'));
-- 13.12 Catégorie B1 ou B2 et habitant à Lille ou GrenobleSELECT * FROM Clients WHERE (categorie = 'B1' OR categorie = 'B2') AND (ville = 'Lille' OR ville = 'Grenoble');
-- 13.13 Pas sélectionné dans la question précédenteSELECT * FROM Clients WHERE numero NOT IN ( SELECT numero FROM Clients WHERE (categorie = 'B1' OR categorie = 'B2') AND (ville = 'Lille' OR ville = 'Grenoble'));
-- 14. Valeur totale des stocks de tous les produitsSELECT SUM(stock * prix) AS valeur_totaleFROM Produits;
-- 15. Produits contenant la lettre 'u' dans leur nom
SELECT numero, nomFROM ProduitsWHERE nom LIKE '%u%';
-- 15.1 Qui ne sont pas commandésSELECT numero, nomFROM ProduitsWHERE nom LIKE '%u%'AND numero NOT IN ( SELECT numeroProduit FROM Details);
-- 15.2 Qui sont commandés à MeylanSELECT DISTINCT numero, nomFROM ProduitsWHERE nom LIKE '%u%'AND numero IN ( SELECT numeroProduit FROM Details WHERE numeroCommande IN ( SELECT numero FROM Commandes WHERE numeroClient IN ( SELECT numero FROM Clients WHERE ville = 'Meylan' ) ));
-- Version JOINSELECT DISTINCT Produits.numero, Produits.nomFROM ProduitsJOIN Details ON Produits.numero = Details.numeroProduitJOIN Commandes ON Details.numeroCommande = Commandes.numeroJOIN Clients ON Commandes.numeroClient = Clients.numeroWHERE Produits.nom LIKE '%u%' AND Clients.ville = 'Meylan';
-- 15.3 Qui ne sont pas commandés à MeylanSELECT DISTINCT numero, nomFROM ProduitsWHERE nom LIKE '%u%'AND numero NOT IN ( SELECT numeroProduit FROM Details WHERE numeroCommande IN ( SELECT numero FROM Commandes WHERE numeroClient IN ( SELECT numero FROM Clients WHERE ville = 'Meylan' ) ));
-- Version JOINSELECT DISTINCT Produits.numero, Produits.nomFROM ProduitsWHERE Produits.nom LIKE '%u%'AND numero NOT IN ( SELECT Produits.numero FROM Produits JOIN Details ON Produits.numero = Details.numeroProduit JOIN Commandes ON Details.numeroCommande = Commandes.numero JOIN Clients ON Commandes.numeroClient = Clients.numero WHERE Clients.ville = 'Meylan');
-- 15.4 Qui ne sont commandés qu'à MeylanSELECT DISTINCT numero, nomFROM ProduitsWHERE numero IN ( SELECT numeroProduit FROM Details WHERE numeroCommande IN ( SELECT numero FROM Commandes WHERE numeroClient IN ( SELECT numero FROM Clients WHERE ville = 'Meylan' ) ))AND numero NOT IN ( SELECT numeroProduit FROM Details WHERE numeroCommande IN ( SELECT numero FROM Commandes WHERE numeroClient IN ( SELECT numero FROM Clients WHERE ville <> 'Meylan' ) ));
-- Version JOINSELECT DISTINCT Produits.numero, Produits.nomFROM ProduitsJOIN Details ON Produits.numero = Details.numeroProduitJOIN Commandes ON Details.numeroCommande = Commandes.numeroJOIN Clients ON Commandes.numeroClient = Clients.numeroWHERE Clients.ville = 'Meylan'AND Produits.numero NOT IN ( SELECT Produits.numero FROM Produits JOIN Details ON Produits.numero = Details.numeroProduit JOIN Commandes ON Details.numeroCommande = Commandes.numero JOIN Clients ON Commandes.numeroClient = Clients.numero WHERE Clients.ville <> 'Meylan');
-- 15.5 Qui ne sont pas commandés qu'à MeylanSELECT DISTINCT numero, nomFROM ProduitsWHERE nom LIKE '%u%'AND numero IN ( SELECT numeroProduit FROM Details)AND numero IN ( SELECT numeroProduit FROM Details WHERE numeroCommande IN ( SELECT numero FROM Commandes WHERE numeroClient IN ( SELECT numero FROM Clients WHERE ville <> 'Meylan' ) ));
-- Version JOINSELECT DISTINCT Produits.numero, Produits.nomFROM ProduitsWHERE Produits.nom LIKE '%u%'AND Produits.numero IN ( SELECT numeroProduit FROM Details)AND Produits.numero IN ( SELECT Produits.numero FROM Produits JOIN Details ON Produits.numero = Details.numeroProduit JOIN Commandes ON Details.numeroCommande = Commandes.numero JOIN Clients ON Commandes.numeroClient = Clients.numero WHERE Clients.ville <> 'Meylan');
-- 15.6 Qui sont commandés à Meylan, mais aussi ailleursSELECT DISTINCT numero, nomFROM ProduitsWHERE numero IN ( -- Produits commandés par des clients à Meylan SELECT numeroProduit FROM Details WHERE numeroCommande IN ( SELECT numero FROM Commandes WHERE numeroClient IN ( SELECT numero FROM Clients WHERE ville = 'Meylan' ) ))AND numero IN ( -- Produits également commandés par des clients qui ne sont pas à Meylan SELECT numeroProduit FROM Details WHERE numeroCommande IN ( SELECT numero FROM Commandes WHERE numeroClient IN ( SELECT numero FROM Clients WHERE ville <> 'Meylan' ) ));
-- Version JOINSELECT DISTINCT Produits.numero, Produits.nomFROM ProduitsJOIN Details ON Produits.numero = Details.numeroProduitJOIN Commandes ON Details.numeroCommande = Commandes.numeroJOIN Clients ON Commandes.numeroClient = Clients.numeroWHERE Clients.ville = 'Meylan'AND Produits.numero IN ( SELECT Produits.numero FROM Produits JOIN Details ON Produits.numero = Details.numeroProduit JOIN Commandes ON Details.numeroCommande = Commandes.numero JOIN Clients ON Commandes.numeroClient = Clients.numero WHERE Clients.ville <> 'Meylan');
-- 16. Nombre de commandes spécifiant un produit contenant la lettre 'u'SELECT COUNT(DISTINCT numeroCommande)FROM DetailsWHERE numeroProduit IN ( SELECT numero FROM Produits WHERE nom LIKE '%u%');
-- Version JOINSELECT COUNT(DISTINCT Details.numeroCommande)FROM DetailsJOIN Produits ON Details.numeroProduit = Produits.numeroWHERE Produits.nom LIKE '%u%';
-- 17. Nombre de villes avec des clients de catégorie B2SELECT COUNT(DISTINCT ville)FROM ClientsWHERE categorie = 'B2';
-- 18. Numéro et nom des clients qui n'ont pas commandé de produits contenant la lettre 'u'SELECT numero, nomFROM ClientsWHERE numero NOT IN ( SELECT numeroClient FROM Commandes WHERE numero IN ( SELECT numeroCommande FROM Details WHERE numeroProduit IN ( SELECT numero FROM Produits WHERE nom LIKE '%u%' ) ));
-- Version JOINSELECT numero, nomFROM ClientsWHERE numero NOT IN ( SELECT Commandes.numeroClient FROM Commandes JOIN Details ON Commandes.numero = Details.numeroCommande JOIN Produits ON Details.numeroProduit = Produits.numero WHERE Produits.nom LIKE '%u%');
-- 19. Villes où le produit numéro 1 n'a pas été commandé
-- Requête 1 (incorrecte)SELECT DISTINCT villeFROM ClientsWHERE numero IN ( SELECT numeroClient FROM Commandes WHERE numero NOT IN ( SELECT numeroCommande FROM Details WHERE numeroProduit = 1 ));
-- Requête 2 (incorrecte)SELECT DISTINCT villeFROM ClientsWHERE numero NOT IN ( SELECT numeroClient FROM Commandes WHERE numero IN ( SELECT numeroCommande FROM Details WHERE numeroProduit = 1 ));
-- Requête 3 (correcte)SELECT DISTINCT villeFROM ClientsWHERE ville NOT IN ( SELECT ville FROM Clients WHERE numero IN ( SELECT numeroClient FROM Commandes WHERE numero IN ( SELECT numeroCommande FROM Details WHERE numeroProduit = 1 ) ));
-- 20. Villes où des commandes ont été passées en juin 2024SELECT DISTINCT villeFROM ClientsWHERE numero IN ( SELECT numeroClient FROM Commandes WHERE dateCommande BETWEEN '2024-06-01' AND '2024-06-30');
-- Version JOINSELECT DISTINCT villeFROM ClientsJOIN Commandes ON Clients.numero = Commandes.numeroClientWHERE Commandes.dateCommande BETWEEN '2024-06-01' AND '2024-06-30';
-- 21. Requête pour vérifier les anomalies de clé étrangère dans la table DetailsSELECT *FROM DetailsWHERE numeroCommande NOT IN (SELECT numero FROM Commandes);
-- 22. Vérification que chaque commande a au moins un détailSELECT *FROM CommandesWHERE numero NOT IN ( SELECT numeroCommande FROM Details);
-- 23. Produits (numéro et nom) qui n'ont pas été commandés en 2024SELECT numero, nomFROM ProduitsWHERE numero NOT IN ( SELECT numeroProduit FROM Details WHERE numeroCommande IN ( SELECT numero FROM Commandes WHERE dateCommande BETWEEN '2024-01-01' AND '2024-12-31' ));
-- Version JOINSELECT numero, nomFROM ProduitsWHERE numero NOT IN ( SELECT numeroProduit FROM Details JOIN Commandes ON Details.numeroCommande = Commandes.numero WHERE Commandes.dateCommande BETWEEN '2024-01-01' AND '2024-12-31');
-- 24. Clients qui ont commandé tous les produitsSELECT DISTINCT numero, nomFROM ClientsWHERE NOT EXISTS ( SELECT * FROM Produits WHERE NOT EXISTS ( SELECT * FROM Commandes WHERE numeroClient = Clients.numero AND numero IN ( SELECT numeroCommande FROM Details WHERE numeroProduit = Produits.numero ) ));
-- Version JOINSELECT DISTINCT Clients.numero, Clients.nomFROM ClientsWHERE NOT EXISTS ( SELECT * FROM Produits WHERE NOT EXISTS ( SELECT * FROM Commandes JOIN Details ON Commandes.numero = Details.numeroCommande WHERE Commandes.numeroClient = Clients.numero AND Details.numeroProduit = Produits.numero ));
-- 25. Villes où tous les produits ont été commandés (tous clients confondusSELECT DISTINCT villeFROM ClientsWHERE numero IN ( SELECT numeroClient FROM Commandes WHERE NOT EXISTS ( SELECT * FROM Produits WHERE NOT EXISTS ( SELECT * FROM Details WHERE Details.numeroProduit = Produits.numero AND Details.numeroCommande = Commandes.numero ) ));
-- Version JOINSELECT DISTINCT villeFROM ClientsJOIN Commandes ON Clients.numero = Commandes.numeroClientWHERE NOT EXISTS ( SELECT * FROM Produits WHERE NOT EXISTS ( SELECT * FROM Details WHERE Details.numeroProduit = Produits.numero AND Details.numeroCommande = Commandes.numero ));
-- 26. Produits qui ont été commandés par tous les clientsSELECT DISTINCT Produits.numero, Produits.nomFROM ProduitsWHERE NOT EXISTS ( SELECT * FROM Clients WHERE NOT EXISTS ( SELECT * FROM Commandes JOIN Details ON Commandes.numero = Details.numeroCommande WHERE Commandes.numeroClient = Clients.numero AND Details.numeroProduit = Produits.numero ));
-- 27. Villes dont aucun client n'a passé de commandeSELECT DISTINCT villeFROM ClientsWHERE numero NOT IN ( SELECT numeroClient FROM Commandes);
-- 28. Villes dont tous les clients ont passé au moins une commandeSELECT DISTINCT villeFROM ClientsWHERE NOT EXISTS ( SELECT * FROM Clients AS C WHERE Clients.ville = C.ville AND C.numero NOT IN (SELECT numeroClient FROM Commandes));
-- 29. Produits commandés dans toutes les villesSELECT DISTINCT numero, nomFROM ProduitsWHERE NOT EXISTS ( SELECT * FROM Clients WHERE NOT EXISTS ( SELECT * FROM Commandes WHERE numeroClient = Clients.numero AND numero IN ( SELECT numeroCommande FROM Details WHERE numeroProduit = Produits.numero ) ));
-- Version JOINSELECT DISTINCT Produits.numero, Produits.nomFROM ProduitsWHERE NOT EXISTS ( SELECT * FROM Clients WHERE NOT EXISTS ( SELECT * FROM Commandes JOIN Details ON Commandes.numero = Details.numeroCommande WHERE Commandes.numeroClient = Clients.numero AND Details.numeroProduit = Produits.numero ));