21
Chapitre 21 sur 21

Mini-projet final guidé

Vous allez maintenant réaliser un mini-projet complet pour réutiliser tout ce que vous avez appris : créer une petite base, modéliser les tables, insérer des données, faire des JOIN, écrire des statistiques avec GROUP BY et produire des requêtes “version pro”.

Contexte du projet : mini-boutique (commandes)

On va créer une petite base pour une boutique très simple : des clients, des produits et des commandes. Une commande peut contenir plusieurs produits, donc on utilisera une table de liaison.

🛒

Pourquoi ce sujet ?

C’est un cas réel qu’on retrouve partout (e-commerce, réservation, facturation). Il couvre PK/FK, relations 1-N et N-N, JOIN, agrégations et bonnes pratiques.

Objectifs du mini-projet

🏗️

Modéliser

Définir des tables propres (PK, FK, contraintes).

✍️

Créer & remplir

CREATE TABLE + INSERT de données de test.

🔗

Relier

JOIN pour afficher des données “riches”.

📊

Analyser

COUNT/SUM/AVG + GROUP BY/HAVING.

Étape 1 : créer la base et les tables

Vous pouvez exécuter ce script tel quel dans votre outil SQL. Il est volontairement simple et clair.

-- 1) Base (selon votre outil, cette partie peut être optionnelle)
CREATE DATABASE boutique_sql;
USE boutique_sql;

-- 2) Table clients
CREATE TABLE clients (
  id INT PRIMARY KEY AUTO_INCREMENT,
  nom VARCHAR(100) NOT NULL,
  email VARCHAR(150) NOT NULL UNIQUE
);

-- 3) Table produits
CREATE TABLE produits (
  id INT PRIMARY KEY AUTO_INCREMENT,
  nom VARCHAR(120) NOT NULL,
  prix DECIMAL(10,2) NOT NULL CHECK (prix >= 0)
);

-- 4) Table commandes (1 client -> N commandes)
CREATE TABLE commandes (
  id INT PRIMARY KEY AUTO_INCREMENT,
  client_id INT NOT NULL,
  date_commande DATE NOT NULL,
  FOREIGN KEY (client_id) REFERENCES clients(id)
);

-- 5) Table de liaison (commande -> N produits) + quantité
CREATE TABLE commande_produit (
  commande_id INT NOT NULL,
  produit_id INT NOT NULL,
  quantite INT NOT NULL CHECK (quantite > 0),
  PRIMARY KEY (commande_id, produit_id),
  FOREIGN KEY (commande_id) REFERENCES commandes(id),
  FOREIGN KEY (produit_id) REFERENCES produits(id)
);

À comprendre

commande_produit est la table N-N : une commande contient plusieurs produits, et un produit peut apparaître dans plusieurs commandes.

Étape 2 : insérer des données de test

Insérez quelques lignes pour pouvoir tester vos requêtes.

INSERT INTO clients (nom, email) VALUES
('Alice Martin', 'alice@mail.com'),
('Yanis Dupont', 'yanis@mail.com'),
('Nora Benali', 'nora@mail.com');

INSERT INTO produits (nom, prix) VALUES
('Burger', 8.50),
('Frites', 3.00),
('Soda', 2.50),
('Salade', 6.00);

INSERT INTO commandes (client_id, date_commande) VALUES
(1, '2024-01-10'),
(2, '2024-01-11'),
(1, '2024-01-12');

INSERT INTO commande_produit (commande_id, produit_id, quantite) VALUES
(1, 1, 1),
(1, 2, 1),
(1, 3, 2),
(2, 4, 1),
(2, 3, 1),
(3, 1, 2),
(3, 2, 2);
⚠️

Si vous avez une erreur

Si une contrainte bloque (UNIQUE, FK…), relisez le Chapitre 19 : vous avez maintenant les réflexes pour corriger rapidement.

Étape 3 : requêtes indispensables

Voici une série de requêtes progressives. Testez-les une par une.

-- A) Afficher toutes les commandes avec le nom du client
SELECT co.id, co.date_commande, c.nom
FROM commandes co
JOIN clients c ON co.client_id = c.id;

-- B) Détails d'une commande : produits + quantité
SELECT
  co.id AS commande_id,
  p.nom AS produit,
  cp.quantite,
  p.prix
FROM commandes co
JOIN commande_produit cp ON cp.commande_id = co.id
JOIN produits p ON p.id = cp.produit_id
WHERE co.id = 1;

-- C) Total d'une commande (somme prix * quantité)
SELECT
  co.id AS commande_id,
  SUM(p.prix * cp.quantite) AS total_commande
FROM commandes co
JOIN commande_produit cp ON cp.commande_id = co.id
JOIN produits p ON p.id = cp.produit_id
WHERE co.id = 1
GROUP BY co.id;
🧠

Lecture

Le total = prix du produit × quantite, puis on additionne (SUM).

Étape 4 : statistiques (GROUP BY / HAVING)

Maintenant, on passe en mode “tableau de bord”.

-- A) Nombre de commandes par client
SELECT c.nom, COUNT(co.id) AS nb_commandes
FROM clients c
LEFT JOIN commandes co ON co.client_id = c.id
GROUP BY c.id, c.nom
ORDER BY nb_commandes DESC;

-- B) Chiffre d'affaires par client
SELECT
  c.nom,
  SUM(p.prix * cp.quantite) AS chiffre_affaires
FROM clients c
JOIN commandes co ON co.client_id = c.id
JOIN commande_produit cp ON cp.commande_id = co.id
JOIN produits p ON p.id = cp.produit_id
GROUP BY c.id, c.nom
ORDER BY chiffre_affaires DESC;

-- C) Garder uniquement les clients au-dessus de 15€
SELECT
  c.nom,
  SUM(p.prix * cp.quantite) AS chiffre_affaires
FROM clients c
JOIN commandes co ON co.client_id = c.id
JOIN commande_produit cp ON cp.commande_id = co.id
JOIN produits p ON p.id = cp.produit_id
GROUP BY c.id, c.nom
HAVING SUM(p.prix * cp.quantite) > 15
ORDER BY chiffre_affaires DESC;

Étape 5 : appliquer les bonnes pratiques (chapitre 20)

Avant de conclure, vérifiez que vos requêtes respectent ces points :

🧾

Colonnes explicites

Évitez SELECT * dans les requêtes “finales”.

🔎

Alias cohérents

c, co, p, cp pour rester lisible.

🛡️

Sécurité

Avant UPDATE/DELETE : testez avec un SELECT identique.

🚀

Performance

Index possibles : commandes.client_id, commande_produit.commande_id.

Mission finale (à faire seul)

Vous avez maintenant toutes les briques. Réalisez ces requêtes sans regarder la correction, puis comparez.

1) Liste des produits vendus

Afficher chaque produit + le total des quantités vendues.

2) Top produit

Le produit le plus vendu (quantité totale la plus haute).

3) Dernières commandes

Les 5 dernières commandes avec le nom du client.

Bonus

Client “le plus rentable” (plus gros chiffre d’affaires).

🧠

Indice

Tout se fait avec JOIN + SUM/COUNT + GROUP BY + ORDER BY + LIMIT.

Récapitulatif final

🏁

Vous avez terminé le cours

  • Créer une base et des tables (CREATE TABLE, PK/FK)
  • Insérer et gérer des données (INSERT, UPDATE, DELETE)
  • Lire et filtrer (SELECT, WHERE, ORDER BY, LIMIT)
  • Relier des tables (JOIN, N-N)
  • Faire des statistiques (COUNT, SUM, AVG, GROUP BY, HAVING)
  • Corriger les erreurs et appliquer de bonnes pratiques

Si vous voulez aller plus loin, la suite logique est : index avancés, vues (VIEW), procédures/fonctions, et optimisation.