Premiers pas pratiques en SQL sur une vraie base de données : 20 clients, 12 voitures et 200 locations à interroger. Tu apprends à importer la base dans HeidiSQL et phpMyAdmin, puis tu écris tes premières requêtes pour chercher, filtrer et trier.
Tu as vu comment une base relationnelle est structurée. Maintenant on l'utilise pour de vrai : on importe une base existante et on commence à l'interroger avec SQL. À la fin de ce cours, tu sauras répondre à des questions concrètes comme « quelles locations sont en cours ? » ou « quels sont les modèles à moins de 50 € par jour, triés du moins cher au plus cher ? ».
À la fin de ce cours, tu seras capable de :
.sql dans HeidiSQL et dans phpMyAdmin.SELECT … FROM … pour afficher des lignes.WHERE et les opérateurs =, <>, <, >, LIKE.AND et OR.ORDER BY (croissant, décroissant, multi-colonnes).Avant de pouvoir écrire des requêtes, il faut importer la base dans ton SGBD. Télécharge d'abord le fichier location_voitures_4e_ttinfo.sql via le lien de téléchargement à droite de cette page.
ℹ️ C'est quoi un fichier
.sql? C'est un script texte qui contient des instructions SQL :CREATE TABLE,INSERT INTO, etc. Quand tu l'« exécutes » dans un SGBD, il rejoue toutes ces instructions et reconstruit la base de zéro.
Hôte: 127.0.0.1, Utilisateur: root, mot de passe vide).location_voitures, valide.location_voitures_4e_ttinfo.sql dans tes téléchargements. Une nouvelle requête s'ouvre.location_voitures. Tu dois voir 3 tables : client, voiture, location.⚠️ Si HeidiSQL refuse : vérifie que tu as bien double-cliqué sur la base
location_voitures(et pas une autre) avant d'exécuter le script — lesCREATE TABLEse font dans la base active.
http://localhost/phpmyadmin dans ton navigateur.location_voitures dans le champ « Créer une base de données » → clique Créer.location_voitures à gauche pour t'y placer.location_voitures_4e_ttinfo.sql.💡 HeidiSQL vs phpMyAdmin : tu obtiens exactement la même base, parce que les deux parlent au même serveur MySQL. Tu peux ouvrir les deux clients en même temps : ce que tu fais d'un côté apparaît immédiatement de l'autre.
Quel que soit le client utilisé, ouvre une nouvelle requête SQL et tape :
SELECT COUNT(*) FROM location;
Tu dois obtenir 200. Si oui, ta base est prête.
La base contient 3 tables liées par des clés étrangères :
┌─────────────────┐ ┌──────────────────┐
│ client │ │ voiture │
├─────────────────┤ ├──────────────────┤
│ id_client (PK) │ │ id_voiture (PK) │
│ nom │ │ modele │
│ prenom │ │ marque │
│ telephone │ │ prix_jour │
└────────┬────────┘ └────────┬─────────┘
│ │
│ 1 1 │
│ │
│ N ┌───────┐ N │
└─────────►│ location│◄─────┘
├───────┤
│ id_location (PK)
│ id_client (FK)
│ id_voiture (FK)
│ date_location
│ date_retour
│ statut
└───────┘
Un client peut faire plusieurs locations. Une voiture peut être louée plusieurs fois. Chaque ligne de location fait le lien entre un client et une voiture, à une date donnée.
client| Colonne | Type | Description |
|---|---|---|
id_client |
INT (PK) |
Identifiant interne (auto-incrément) |
nom |
VARCHAR(50) |
Nom de famille |
prenom |
VARCHAR(50) |
Prénom |
telephone |
VARCHAR(20) |
Numéro (unique) |
voiture| Colonne | Type | Description |
|---|---|---|
id_voiture |
INT (PK) |
Identifiant interne |
modele |
VARCHAR(50) |
Modèle (Clio, Golf, A3…) |
marque |
VARCHAR(50) |
Marque (Renault, VW, Audi…) |
prix_jour |
DECIMAL(6,2) |
Prix de location par jour, en € |
location| Colonne | Type | Description |
|---|---|---|
id_location |
VARCHAR(5) (PK) |
Code lisible (L001, L002) |
id_client |
INT (FK → client) |
Qui loue |
id_voiture |
INT (FK → voiture) |
Quelle voiture |
date_location |
DATE |
Date de début |
date_retour |
DATE |
Date de retour |
statut |
ENUM('terminée','en cours','réservée','annulée') |
État de la location |
SELECT et FROM : lire des lignesC'est la requête la plus simple. Elle dit « lis cette table ».
SELECT *SELECT *
FROM client;
L'étoile * veut dire toutes les colonnes. Tu obtiens les 20 clients avec toutes leurs infos :
| id_client | nom | prenom | telephone |
|---|---|---|---|
| 1 | Dupont | Marie | 0471 12 34 56 |
| 2 | Martin | Lucas | 0485 22 11 00 |
| 3 | Lambert | Sophie | 0492 44 55 66 |
| … | … | … | … |
(20 lignes au total)
Quand tu n'as besoin que de certaines colonnes, liste-les explicitement après SELECT, séparées par des virgules :
SELECT nom, prenom
FROM client;
Tu obtiens seulement 2 colonnes (et toujours 20 lignes) :
| nom | prenom |
|---|---|
| Dupont | Marie |
| Martin | Lucas |
| Lambert | Sophie |
| … | … |
🧠 Bonne pratique : préfère lister les colonnes plutôt que
SELECT *. C'est plus lisible, plus rapide, et ça évite les surprises si quelqu'un ajoute une colonne à la table.
Quand une table contient des centaines ou des milliers de lignes (comme location, avec ses 200 entrées), SELECT * t'inonde la console. La clause LIMIT n dit « ne montre que les n premières lignes ».
SELECT *
FROM location
LIMIT 5;
Très pratique pour jeter un œil à une grande table sans tout charger.
WHERE : filtrer les lignesSELECT … FROM … lit toutes les lignes. Si tu veux uniquement celles qui remplissent une condition, ajoute une clause WHERE.
=Quelles sont les locations dont le statut est « en cours » ?
SELECT id_location, id_client, date_location, date_retour
FROM location
WHERE statut = 'en cours';
Tu obtiens uniquement les lignes où statut vaut exactement 'en cours'. Une trentaine de lignes au lieu de 200.
⚠️ Les chaînes vont entre guillemets simples :
'en cours'. Les nombres, eux, s'écrivent sans guillemets :id_client = 5. Pasid_client = '5'(ça marcherait par chance, mais c'est faux conceptuellement).
| Opérateur | Sens | Exemple |
|---|---|---|
= |
égal | prix_jour = 50 |
<> ou != |
différent de | statut <> 'annulée' |
< |
strictement inférieur | prix_jour < 50 |
> |
strictement supérieur | prix_jour > 60 |
<= |
inférieur ou égal | prix_jour <= 50 |
>= |
supérieur ou égal | id_client >= 10 |
SELECT modele, marque, prix_jour
FROM voiture
WHERE prix_jour > 60;
Résultat :
| modele | marque | prix_jour |
|---|---|---|
| A3 | Audi | 75.00 |
| Civic | Honda | 62.00 |
LIKEPour chercher dans une chaîne sans donner sa valeur exacte, on utilise LIKE combiné avec le joker % (qui remplace zéro ou plusieurs caractères).
Quels sont les clients dont le nom commence par « L » ?
SELECT nom, prenom
FROM client
WHERE nom LIKE 'L%';
Résultat :
| nom | prenom |
|---|---|
| Lambert | Sophie |
| Leroy | Emma |
| Laurent | Adam |
| Leclercq | Tom |
💡 Quelques motifs utiles :
'L%'→ commence par L (Lambert, Leroy…)'%n'→ finit par n (Dupont, Martin, Simon…)'%art%'→ contient « art » (Martin, Bernard…)'D____'→ exactement 5 caractères, commence par D (_remplace UN caractère)
AND et ORAND — toutes les conditions doivent être vraiesQuelles locations sont en cours ET concernent le client 4 ?
SELECT id_location, date_location, date_retour
FROM location
WHERE statut = 'en cours' AND id_client = 4;
OR — au moins une condition doit être vraieQuelles voitures sont des Renault OU des VW ?
SELECT modele, marque, prix_jour
FROM voiture
WHERE marque = 'Renault' OR marque = 'VW';
⚠️ Attention à l'ordre des conditions quand tu mélanges
ANDetOR. Comme en mathématiques,ANDa priorité surOR. En cas de doute, mets des parenthèses :WHERE (marque = 'Renault' OR marque = 'VW') AND prix_jour < 55
ORDER BY : trier les résultatsPar défaut, les lignes reviennent dans l'ordre où la base les a en stock — c'est-à-dire dans n'importe quel ordre. Pour les trier, on ajoute une clause ORDER BY.
SELECT modele, marque, prix_jour
FROM voiture
ORDER BY prix_jour;
Les voitures sortent triées du moins cher au plus cher :
| modele | marque | prix_jour |
|---|---|---|
| 500 | Fiat | 40.00 |
| Corsa | Opel | 42.00 |
| Fiesta | Ford | 43.00 |
| Clio | Renault | 45.00 |
| Yaris | Toyota | 48.00 |
| 208 | Peugeot | 50.00 |
| … | … | … |
ℹ️
ASCest implicite :ORDER BY prix_jouretORDER BY prix_jour ASCfont la même chose. Le mot-cléASC(ascending) est juste là pour être explicite.
DESCLes voitures les plus chères d'abord :
SELECT modele, marque, prix_jour
FROM voiture
ORDER BY prix_jour DESC;
Tu peux trier sur plusieurs critères : la première colonne est le critère principal, la suivante départage les égalités.
Les clients par nom, puis par prénom en cas d'homonymie :
SELECT nom, prenom, telephone
FROM client
ORDER BY nom ASC, prenom ASC;
Les quatre clauses SELECT / FROM / WHERE / ORDER BY se combinent dans cet ordre :
SELECT colonnes -- QUOI afficher
FROM table -- OÙ chercher
WHERE conditions -- QUELLES lignes garder
ORDER BY colonne(s) -- COMMENT trier
LIMIT n; -- (optionnel) Combien
Les 10 locations les plus anciennes dont le statut est terminée, triées de la plus ancienne à la plus récente :
SELECT id_location, id_client, date_location, date_retour
FROM location
WHERE statut = 'terminée'
ORDER BY date_location ASC
LIMIT 10;
Énoncé. Tu veux la liste des locations en cours, triées de la plus récente à la plus ancienne, mais seulement les 5 premières.
Au lieu d'écrire la requête finale d'un coup, on la construit par couches — c'est la bonne façon de faire en SQL.
Premier brouillon : afficher toutes les locations, sans filtre.
SELECT id_location, date_location, statut
FROM location;
→ 200 lignes. C'est beaucoup. On commence à filtrer.
SELECT id_location, date_location, statut
FROM location
WHERE statut = 'en cours';
→ Une trentaine de lignes. On a déjà bien réduit.
SELECT id_location, date_location, statut
FROM location
WHERE statut = 'en cours'
ORDER BY date_location DESC;
→ Les locations apparaissent maintenant du plus récent au plus ancien.
SELECT id_location, date_location, statut
FROM location
WHERE statut = 'en cours'
ORDER BY date_location DESC
LIMIT 5;
→ 5 lignes, exactement comme demandé.
🧠 Le réflexe à acquérir : ne tape jamais une requête complexe d'un seul coup. Commence par
SELECT * FROM table LIMIT 5pour voir la donnée, puis ajoute une clause à la fois en vérifiant le résultat à chaque étape.
Pour chacun, écris la requête, exécute-la dans HeidiSQL ou phpMyAdmin, et vérifie le nombre de lignes attendu.
ORDER BY + LIMIT.BETWEEN '2026-08-01' AND '2026-08-31').LIKE 'A%' OR LIKE 'E%' OR …SELECT colonnes, FROM table, (WHERE, ORDER BY, LIMIT optionnels)*.SELECT * prend toutes les colonnes. SELECT col1, col2 ne prend que celles listées (à préférer).WHERE filtre les lignes. Opérateurs : =, <>, <, >, <=, >=, LIKE, combinés avec AND / OR.WHERE statut = 'terminée'.LIKE + le joker % cherche dans une chaîne (commence par, finit par, contient).ORDER BY trie. ASC = croissant (par défaut), DESC = décroissant. Plusieurs colonnes possibles.LIMIT n garde uniquement les n premières lignes — utile pour explorer ou pour un top N.Tu sais maintenant interroger une seule table à la fois. Mais regarde tes requêtes sur location : tu vois id_client = 4 au lieu de « Dubois Nora », et id_voiture = 11 au lieu de « Fiat 500 ». Pour afficher les vrais noms à la place des identifiants, il faut combiner plusieurs tables dans une seule requête — c'est le rôle des jointures, sujet du cours suivant.