Aller au contenu

Exercices de pratique — Requêtes SQL

Modèles de bases de données

Modèle 1 — Club vidéo

Utilisé pour les exercices 1, 2, 3, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 19

erDiagram
    realisateurs ||--o{ films : "a réalisé"
    distributeurs ||--o{ films : "distribue"
    films ||--o{ locations : "est loué"
    membres ||--o{ locations : "loue"

    realisateurs {
        INT realisateur_id PK
        VARCHAR nom
        VARCHAR prenom
        VARCHAR nationalite
        DATE date_de_naissance
    }
    distributeurs {
        INT distributeur_id PK
        VARCHAR nom
        VARCHAR adresse
        VARCHAR telephone
    }
    films {
        INT film_id PK
        VARCHAR titre
        INT realisateur_id FK
        INT distributeur_id FK
        INT annee_sortie
        VARCHAR genre
    }
    membres {
        INT membre_id PK
        VARCHAR nom
        VARCHAR prenom
        VARCHAR adresse
        DATE date_adhesion
        VARCHAR courriel
    }
    locations {
        INT location_id PK
        INT film_id FK
        INT membre_id FK
        DATE date_location
        DATE date_retour
    }

Modèle 2 — Boutique en ligne

Utilisé pour les exercices 4, 5, 9, 17, 18, 20

erDiagram
    categories ||--o{ produits : "contient"
    clients ||--o{ commandes : "passe"
    commandes ||--|{ lignes_commandes : "contient"
    produits ||--o{ lignes_commandes : "inclus dans"

    categories {
        INT categorie_id PK
        VARCHAR nom
    }
    produits {
        INT produit_id PK
        VARCHAR nom
        TEXT description
        DECIMAL prix
        INT stock
        INT categorie_id FK
    }
    clients {
        INT client_id PK
        VARCHAR nom
        VARCHAR prenom
        VARCHAR courriel
        DATE date_inscription
        VARCHAR ville
    }
    commandes {
        INT commande_id PK
        INT client_id FK
        DATE date_commande
        VARCHAR statut
    }
    lignes_commandes {
        INT ligne_id PK
        INT commande_id FK
        INT produit_id FK
        INT quantite
        DECIMAL prix_unitaire
    }

Partie 1 — Création et manipulation de structures

Exercice 1

Modèle : Club vidéo

Écrivez la requête pour créer la table membres. Les clés primaires non composées de type entier doivent être auto-incrémentées.

Type Colonne Contrainte
INT membre_id PK
VARCHAR(255) nom NOT NULL
VARCHAR(255) prenom NOT NULL
VARCHAR(255) adresse
DATE date_adhesion
VARCHAR(255) courriel
CREATE TABLE membres (
    membre_id INT PRIMARY KEY AUTO_INCREMENT,
    nom VARCHAR(255) NOT NULL,
    prenom VARCHAR(255) NOT NULL,
    adresse VARCHAR(255),
    date_adhesion DATE,
    courriel VARCHAR(255)
);

Exercice 2

Modèle : Club vidéo

Écrivez la requête pour créer la table locations. Les clés primaires non composées de type entier doivent être auto-incrémentées.

Type Colonne Contrainte
INT location_id PK
INT film_id FK → films
INT membre_id FK → membres
DATE date_location
DATE date_retour
CREATE TABLE locations (
    location_id INT PRIMARY KEY AUTO_INCREMENT,
    film_id INT,
    membre_id INT,
    date_location DATE,
    date_retour DATE,
    FOREIGN KEY (film_id) REFERENCES films (film_id),
    FOREIGN KEY (membre_id) REFERENCES membres (membre_id)
);

Exercice 3

Modèle : Club vidéo

Écrivez la requête pour ajouter une colonne date_retour_prevue de type DATE à la table locations.

ALTER TABLE locations
    ADD COLUMN date_retour_prevue DATE;

Exercice 4

Modèle : Boutique en ligne

Écrivez la requête pour créer la table produits. Les clés primaires non composées de type entier doivent être auto-incrémentées.

Type Colonne Contrainte
INT produit_id PK
VARCHAR(255) nom NOT NULL
TEXT description
DECIMAL(10,2) prix NOT NULL
INT stock
INT categorie_id FK → categories
CREATE TABLE produits (
    produit_id INT PRIMARY KEY AUTO_INCREMENT,
    nom VARCHAR(255) NOT NULL,
    description TEXT,
    prix DECIMAL(10, 2) NOT NULL,
    stock INT,
    categorie_id INT,
    FOREIGN KEY (categorie_id) REFERENCES categories (categorie_id)
);

Exercice 5

Modèle : Boutique en ligne

Écrivez la requête pour modifier la colonne description de la table produits afin de changer son type de TEXT à VARCHAR(500).

ALTER TABLE produits
    MODIFY COLUMN description VARCHAR(500);

Partie 2 — Création, mise à jour et suppression de données

Exercice 6

Modèle : Club vidéo

Ajoutez un nouveau réalisateur : Denis Villeneuve, de nationalité canadienne, né le 3 octobre 1967.

INSERT INTO realisateurs (nom, prenom, nationalite, date_de_naissance)
    VALUES ('Villeneuve', 'Denis', 'Canadienne', '1967-10-03');

Exercice 7

Modèle : Club vidéo

Ajoutez un film intitulé « Incendies » du réalisateur avec l'identifiant 12 et du distributeur avec l'identifiant 4, sorti en 2010. Ce film est un drame.

INSERT INTO films (titre, realisateur_id, distributeur_id, annee_sortie, genre)
    VALUES ('Incendies', 12, 4, 2010, 'Drame');

Exercice 8

Modèle : Club vidéo

Le membre avec l'identifiant 78 a changé d'adresse courriel. Mettez à jour son courriel avec la valeur pierre.gagnon@courriel.ca.

UPDATE membres
    SET courriel = 'pierre.gagnon@courriel.ca'
    WHERE membre_id = 78;

Exercice 9

Modèle : Boutique en ligne

En raison d'une promotion, réduisez de 15 % le prix de tous les produits appartenant à la catégorie avec l'identifiant 5.

UPDATE produits
    SET prix = prix * 0.85
    WHERE categorie_id = 5;

Exercice 10

Modèle : Club vidéo

Le membre 221 a retourné le film 3309 le 14 mars 2025 pour la location 87654. Mettez à jour la location avec la date de retour.

UPDATE locations
    SET date_retour = '2025-03-14'
    WHERE location_id = 87654;

Partie 3 — Sélection de données

Exercice 11

Modèle : Club vidéo

Récupérez les noms et prénoms de tous les membres dont le prénom commence par « Ma ».

SELECT nom, prenom
FROM membres
WHERE prenom LIKE 'Ma%';

Exercice 12

Modèle : Club vidéo

Récupérez les noms, prénoms et nationalités des réalisateurs dont la nationalité se termine par « ain » (ex. : Américain, Mexicain).

SELECT nom, prenom, nationalite
FROM realisateurs
WHERE nationalite RLIKE 'ain$';

Exercice 13

Modèle : Club vidéo

Récupérez le titre de chaque film ainsi que le nom complet de son réalisateur (prénom suivi du nom), trié alphabétiquement par titre.

SELECT f.titre, CONCAT(r.prenom, ' ', r.nom) AS realisateur
FROM films f
INNER JOIN realisateurs r ON f.realisateur_id = r.realisateur_id
ORDER BY f.titre;

Exercice 14

Modèle : Club vidéo

Récupérez le nombre de films par genre, trié par nombre de films en ordre décroissant.

SELECT genre, COUNT(*) AS nombre_films
FROM films
GROUP BY genre
ORDER BY nombre_films DESC;

Exercice 15

Modèle : Club vidéo

Récupérez le nom des distributeurs qui distribuent plus de 5 films, ainsi que leur nombre de films. Triez par nombre de films en ordre décroissant.

SELECT d.nom, COUNT(*) AS nombre_films
FROM distributeurs d
INNER JOIN films f ON d.distributeur_id = f.distributeur_id
GROUP BY d.distributeur_id, d.nom
HAVING COUNT(*) > 5
ORDER BY nombre_films DESC;

Exercice 16

Modèle : Club vidéo

Récupérez le nom et le prénom du membre, le titre du film ainsi que la durée de location en jours pour toutes les locations dont la durée a dépassé 7 jours.

SELECT m.nom, m.prenom, f.titre, DATEDIFF(l.date_retour, l.date_location) AS duree_jours
FROM locations l
INNER JOIN membres m ON l.membre_id = m.membre_id
INNER JOIN films f ON l.film_id = f.film_id
WHERE DATEDIFF(l.date_retour, l.date_location) > 7;

Exercice 17

Modèle : Boutique en ligne

Récupérez le nom et prénom des clients, le nom des produits commandés et la quantité commandée pour toutes les commandes dont le statut est livré.

SELECT c.nom, c.prenom, p.nom AS produit, lc.quantite
FROM commandes co
INNER JOIN clients c ON co.client_id = c.client_id
INNER JOIN lignes_commandes lc ON co.commande_id = lc.commande_id
INNER JOIN produits p ON lc.produit_id = p.produit_id
WHERE co.statut = 'livré';

Exercice 18

Modèle : Boutique en ligne

Trouvez les 3 produits qui génèrent le plus grand revenu total (quantité × prix unitaire). Affichez le nom du produit et son revenu total.

SELECT p.nom, SUM(lc.quantite * lc.prix_unitaire) AS revenu_total
FROM produits p
INNER JOIN lignes_commandes lc ON p.produit_id = lc.produit_id
GROUP BY p.produit_id, p.nom
ORDER BY revenu_total DESC
LIMIT 3;

Partie 4 — Correction de requêtes

Chaque requête ci-dessous comporte deux erreurs. Identifiez-les et réécrivez la requête corrigée.


Exercice 19

Modèle : Club vidéo

Sélectionner le nom et le prénom des membres ainsi que le nombre de locations pour ceux qui ont fait au moins 3 locations.

SELECT membres.nom, membres.prenom, COUNT(location_id) AS nombre_locations
FROM membres
INNER JOIN locations ON membres.membre_id = membres.membre_id
GROUP BY membres.membre_id
WHERE nombre_locations >= 3
ORDER BY nombre_locations DESC;

Erreur 1 :

Erreur 2 :

Requête corrigée :

Erreur 1 : ON membres.membre_id = membres.membre_id — La condition de jointure compare membres.membre_id à lui-même. Il faut utiliser locations.membre_id d'un côté de la condition.

Erreur 2 : WHERE nombre_locations >= 3 — On ne peut pas utiliser WHERE pour filtrer sur un alias de fonction d'agrégation, et WHERE doit toujours apparaître avant GROUP BY. Il faut utiliser HAVING.

SELECT membres.nom, membres.prenom, COUNT(location_id) AS nombre_locations
FROM membres
INNER JOIN locations ON membres.membre_id = locations.membre_id
GROUP BY membres.membre_id
HAVING nombre_locations >= 3
ORDER BY nombre_locations DESC;

Exercice 20

Modèle : Boutique en ligne

Sélectionner les 5 produits les plus chers encore en stock (stock > 0).

SELECT nom, prix, stock
FROM produits
HAVING stock > 0
ORDER BY prix
LIMIT 5;

Erreur 1 :

Erreur 2 :

Requête corrigée :

Erreur 1 : HAVING stock > 0HAVING est réservé au filtrage après agrégation (GROUP BY). Pour filtrer des lignes ordinaires sans agrégat, il faut utiliser WHERE.

Erreur 2 : ORDER BY prix — Pour obtenir les produits les plus chers, il faut trier par prix en ordre décroissant (DESC).

SELECT nom, prix, stock
FROM produits
WHERE stock > 0
ORDER BY prix DESC
LIMIT 5;