Séance 1 sur 215 livrables
SQL (1) : interroger des données
Une base de données, c'est bien rangé… mais à quoi bon si on ne sait pas lui poser de questions ? Avec SQL, tu demandes : « tous les clients de Lyon », « les produits à moins de 10 € ». Voici le langage qui fait parler les données.
Par Josselyn C., prof de BTS SIO. Publié le , mis à jour le .
- Objectif
- écrire des requêtes SELECT pour lire et filtrer des données (FROM, WHERE, opérateurs, LIKE, AND/OR)
- On manipule
- une vraie base de données, dans un outil SQL (navigateur)
- Pré-requis
- avoir compris la structure d'une base (tables, colonnes, clés)
On écrit de vraies requêtes sur une vraie base : chaque commande renvoie un résultat à l'écran.
Avant de commencer
Pourquoi SQL est incontournable
SQL (Structured Query Language) est le langage pour interroger les bases de données. Tous les SGBD le parlent. Un développeur l'utilise tous les jours : afficher la liste des produits, chercher un client, sortir des statistiques… Et c'est une compétence très demandée, même hors développement (analystes, gestionnaires). Aujourd'hui, tu poses tes premières questions à une base.
Ce que tu sauras faire à la fin
| Mot-clé | Tu sauras… |
|---|---|
SELECT … FROM | choisir les colonnes et la table à lire |
WHERE | filtrer : ne garder que certaines lignes |
| opérateurs | comparer (=, <, >, BETWEEN…) |
LIKE | rechercher dans du texte |
AND / OR | combiner plusieurs conditions |
Le principe en une image
Une requête prend une table, applique un filtre, et te rend un résultat (un sous-tableau). C'est tout le jeu d'aujourd'hui :
0. C'est quoi SQL ?
SQL est un langage où tu écris des questions (des « requêtes ») presque en anglais courant, et la base te renvoie un tableau de résultats. Tu ne dis pas comment chercher (la base s'en occupe), juste ce que tu veux.
| Mot | Définition |
|---|---|
| Requête | une question écrite en SQL |
SELECT | le mot-clé pour lire des données |
| Résultat | le tableau de lignes que la base renvoie |
Un avant-goût : la requête SELECT nom FROM visiteur WHERE ville = 'Lyon'; se lit presque comme une phrase — « donne le nom depuis visiteur où la ville vaut Lyon ». Pas besoin de dire à la base comment chercher : tu décris ce que tu veux, elle le ramène. On démonte chaque mot dans les chapitres suivants.
Flag A1
Checkpoint
Avec tes mots : à quoi sert SQL, et que renvoie une requête SELECT ? Rends : ta réponse.
1. La base de jeu & l'outil
On travaille sur une base d'exemple GSB simplifiée, avec une table visiteur. Garde-la sous les yeux : tous les résultats du playbook se vérifient sur ces 4 lignes.
| id | nom | ville | age | |
|---|---|---|---|---|
| 1 | Marc Dupont | Lyon | 34 | marc.dupont@gsb.fr |
| 2 | Sophie Martin | Paris | 28 | sophie.martin@gsb.fr |
| 3 | Karim Benali | Lyon | 45 | (vide) |
| 4 | Léa Roux | Lille | 31 | lea.roux@gsb.fr |
Remarque la case email de Karim : elle est vide. En base, « vide » porte un nom précis, NULL (= « valeur absente / inconnue »). On apprendra à la traquer au chapitre 6 — souviens-toi de cette ligne.
L'outil
Ouvre sqliteonline.com (ou l'outil indiqué en classe) : à gauche les tables, au centre une zone où tu tapes ta requête, un bouton Run, et en bas le résultat. Colle ce code et clique sur Run (on t'expliquera CREATE/INSERT dans une autre séance ; aujourd'hui, place à SELECT) :
CREATE TABLE visiteur (id INT, nom TEXT, ville TEXT, age INT, email TEXT);
INSERT INTO visiteur VALUES
(1,'Marc Dupont','Lyon',34,'marc.dupont@gsb.fr'),
(2,'Sophie Martin','Paris',28,'sophie.martin@gsb.fr'),
(3,'Karim Benali','Lyon',45,NULL),
(4,'Léa Roux','Lille',31,'lea.roux@gsb.fr');
Écrire un commentaire (et ranger ses requêtes)
Tu peux laisser des notes dans ton SQL : la base les ignore, elles sont juste pour toi.
-- Ceci est un commentaire sur une seule ligne
SELECT * FROM visiteur; -- on peut aussi commenter en fin de ligne
/* Et ça, c'est un commentaire
qui tient sur plusieurs lignes */
Flag B1
Production
Crée la table visiteur avec ses 4 lignes dans l'outil. Rends : confirme que la table existe (elle apparaît à gauche) et contient 4 lignes.
2. SELECT … FROM
La requête de base : choisir des colonnes (SELECT) dans une table (FROM).
SELECT nom, ville FROM visiteur;
La base ne renvoie que les colonnes demandées (nom et ville), pour toutes les lignes.
L'ordre des colonnes, c'est toi qui le décides
Les colonnes s'affichent dans l'ordre où tu les écris dans le SELECT — pas dans l'ordre de la table. Compare :
SELECT ville, nom FROM visiteur;
Même données, en-têtes inversées : pratique pour présenter un résultat dans l'ordre qui t'arrange.
Flag B2
Production
Écris une requête qui affiche uniquement les colonnes nom et age de tous les visiteurs. Rends : ta requête et son résultat.
3. Tout afficher : SELECT *
Pour voir toutes les colonnes, on utilise l'étoile *.
SELECT * FROM visiteur;
Flag B3
Production
Affiche toutes les colonnes de tous les visiteurs avec SELECT *. Rends : ta requête et le nombre de lignes obtenues.
4. Filtrer avec WHERE
Le vrai pouvoir : ne garder que les lignes qui remplissent une condition, avec WHERE.
SELECT nom, ville FROM visiteur
WHERE ville = 'Lyon';
Sur les 4 visiteurs, seuls les 2 Lyonnais sont renvoyés.
Flag B4
Production
Affiche le nom des visiteurs de Paris. Rends : ta requête et son résultat.
5. Comparer : les opérateurs
Avec WHERE, on ne fait pas que tester l'égalité. On compare.
| Opérateur | Sens | Exemple |
|---|---|---|
= | égal | age = 34 |
<> ou != | différent | ville <> 'Lyon' |
< > <= >= | inférieur / supérieur | age > 30 |
BETWEEN … AND … | dans un intervalle | age BETWEEN 30 AND 40 |
IN (…) | dans une liste | ville IN ('Lyon','Paris') |
SELECT nom, age FROM visiteur
WHERE age > 30;
Différent de — <>
SELECT nom, ville FROM visiteur
WHERE ville <> 'Lyon';
Un intervalle — BETWEEN
SELECT nom, age FROM visiteur
WHERE age BETWEEN 30 AND 40;
Une liste de valeurs — IN
SELECT nom, ville FROM visiteur
WHERE ville IN ('Lyon','Paris');
Les types SQL — ce que contient chaque colonne
Le type d'une colonne détermine ce qu'on peut y stocker et comment le comparer. Ce tableau te servira tout au long de GSB Ordonnances :
| Type | Ce qu'il stocke | Plage / taille | Usage typique |
|---|---|---|---|
INT | entier signé 32 bits | −2 147 483 648 → 2 147 483 647 | id, age, quantité |
BIGINT | entier signé 64 bits | ±9 × 10¹⁸ | compteur de clics, clé sur grande table |
DECIMAL(p,d) | nombre exact à virgule | p = chiffres totaux, d = après virgule | DECIMAL(10,2) → montants GSB |
FLOAT / DOUBLE | nombre approché (IEEE 754) | ~7 / ~15 chiffres significatifs | jamais pour l'argent (0,1 + 0,2 ≠ 0,3 en binaire) |
VARCHAR(n) | texte longueur variable | 1 à n caractères (max 65 535 en MySQL) | VARCHAR(100) pour un nom |
TEXT | texte long | jusqu'à 65 535 octets en MySQL | description, commentaire libre |
DATE | date seule (sans heure) | format ISO : YYYY-MM-DD | '2025-01-15' |
DATETIME | date + heure | YYYY-MM-DD HH:MM:SS | horodatage d'une saisie |
Comparer des dates avec les mêmes opérateurs
Si une table a une colonne DATE ou DATETIME, tu compares comme pour les nombres, en respectant le format ISO YYYY-MM-DD :
-- Frais déposés après le 1er mars 2025
SELECT * FROM frais
WHERE date_depot > '2025-03-01';
Le piège fatal de NOT IN avec NULL
Flag B5
Production
Affiche les visiteurs de moins de 35 ans (nom + âge). Puis ceux dont l'âge est entre 30 et 40 (BETWEEN). Puis ceux des villes Lyon ou Lille (IN). Rends : tes 3 requêtes et leurs résultats.
6. Tester l'absence : IS NULL
Souviens-toi : l'email de Karim est vide (NULL). Comment retrouver les lignes où une valeur manque ? Pas avec =, mais avec IS NULL.
SELECT nom, email FROM visiteur
WHERE email IS NULL;
L'inverse — IS NOT NULL
SELECT nom, email FROM visiteur
WHERE email IS NOT NULL;
La logique à trois valeurs : TRUE / FALSE / UNKNOWN
En SQL, une condition ne renvoie pas juste vrai ou faux — elle peut renvoyer UNKNOWN quand un NULL est impliqué. WHERE ne garde que les lignes où la condition vaut TRUE (pas UNKNOWN).
| Expression | Résultat | Pourquoi |
|---|---|---|
NULL = NULL | UNKNOWN | « inconnu = inconnu » n'est pas prouvable |
NULL = 'Lyon' | UNKNOWN | la valeur est peut-être différente, on ne sait pas |
NULL IS NULL | TRUE | IS NULL teste l'absence, pas la valeur |
NULL + 5 | NULL | toute opération arithmétique avec NULL donne NULL |
NULL OR TRUE | TRUE | exception : vrai quoi qu'il en soit de l'inconnu |
NULL AND FALSE | FALSE | exception : faux quoi qu'il en soit de l'inconnu |
Substituer NULL à l'affichage — COALESCE
COALESCE(a, b) renvoie la première valeur non-NULL. Pratique pour afficher un texte de remplacement au lieu d'une case vide :
SELECT nom, COALESCE(email, '— aucun email —') AS email
FROM visiteur;
Flag B6
Production
Affiche le nom et l'email des visiteurs qui ont un email renseigné (IS NOT NULL). Rends : ta requête et son résultat (combien de lignes ?).
7. Rechercher dans du texte : LIKE
Pour chercher un morceau de texte (et pas une valeur exacte), on utilise LIKE avec le joker % (« n'importe quoi »).
SELECT nom FROM visiteur
WHERE nom LIKE '%Martin%';
| Motif | Trouve… | Sur notre table |
|---|---|---|
'Marc%' | commence par « Marc » | Marc Dupont |
'%Dupont' | finit par « Dupont » | Marc Dupont |
'%Roux%' | contient « Roux » | Léa Roux |
L'autre joker : _ (exactement un caractère)
SELECT nom FROM visiteur
WHERE nom LIKE 'M_rc%';
Performance : % en début de motif = scan complet
Ignorer la casse de façon fiable — LOWER()
SELECT nom FROM visiteur
WHERE LOWER(nom) LIKE '%martin%';
Flag B7
Production
Affiche les visiteurs dont le nom contient « a », puis ceux dont le nom commence par « L ». Rends : tes 2 requêtes et leurs résultats.
8. Combiner : AND, OR, NOT
On enchaîne plusieurs conditions pour des filtres plus fins.
SELECT nom FROM visiteur
WHERE ville = 'Lyon' AND age > 40;
Seul Karim est à la fois de Lyon et a plus de 40 ans.
OR — au moins une condition vraie
SELECT nom, ville FROM visiteur
WHERE ville = 'Paris' OR ville = 'Lille';
Flag B8
Production
Affiche les visiteurs qui sont à Lyon OU à Lille. Puis ceux qui ne sont PAS à Lyon (NOT). Rends : tes 2 requêtes et leurs résultats.
9. Renommer une colonne : AS
Le résultat reprend par défaut le nom des colonnes de la table. Avec AS, tu choisis un nom d'affichage plus parlant — sans rien changer dans la table.
SELECT nom AS visiteur, ville AS residence
FROM visiteur;
Flag B9
Production
Affiche la colonne nom sous l'en-tête identite et la colonne age sous l'en-tête annees, pour tous les visiteurs. Rends : ta requête et son résultat (regarde bien les en-têtes).
10. Trier, dédupliquer, limiter
Trier — ORDER BY
SELECT nom, age FROM visiteur
ORDER BY age DESC;
Éviter les doublons — DISTINCT
SELECT DISTINCT ville FROM visiteur;
Limiter — LIMIT
SELECT * FROM visiteur LIMIT 2;
Exemple travaillé — un « top N »
En combinant ORDER BY (trier) puis LIMIT (couper), on obtient les « N premiers ». Le top 2 des plus âgés :
SELECT nom, age FROM visiteur
ORDER BY age DESC
LIMIT 2;
Trier du texte, et sur plusieurs colonnes
ORDER BY marche aussi sur du texte (ordre alphabétique) et sur plusieurs colonnes : la 2ᵉ départage les égalités de la 1ʳᵉ.
SELECT nom, ville, age FROM visiteur
ORDER BY ville ASC, age ASC;
Flag B10
Production
Affiche les villes distinctes. Puis le top 1 du visiteur le plus jeune (trie par âge croissant + LIMIT 1). Puis tous les visiteurs triés par nom de A à Z. Rends : tes 3 requêtes et leurs résultats.
11. Comment SQL lit ta requête
Tu écris SELECT … FROM … WHERE … ORDER BY … LIMIT … dans cet ordre. Mais la base, elle, ne les exécute pas dans cet ordre. Comprendre ça évite la moitié des erreurs.
Majuscules des mots-clés
L'ordre logique complet — avec GROUP BY et HAVING (aperçu)
Tu verras GROUP BY et HAVING à la prochaine séance. Voici déjà l'ordre complet pour ne plus jamais te tromper :
| Étape | Clause | Ce qu'elle fait | Alias utilisable ? |
|---|---|---|---|
| 1 | FROM | ouvre la table (ou la jointure) | non |
| 2 | WHERE | filtre les lignes avant tout calcul | non |
| 3 | GROUP BY | groupe les lignes par valeur de colonne | non (MySQL l'accepte par extension) |
| 4 | HAVING | filtre les groupes après agrégat | non |
| 5 | SELECT | choisit colonnes, calcule, renomme (AS) | c'est ici qu'ils naissent |
| 6 | ORDER BY | trie le résultat final | oui (exception tolérée) |
| 7 | LIMIT | coupe à N lignes | oui |
La requête bien rédigée (style professionnel)
Les SGBD lisent le SQL d'une traite ; les humains préfèrent une mise en forme soignée. Convention en équipe :
-- Visiteurs lyonnais de plus de 30 ans — rapport mensuel GSB
SELECT
nom, -- prénom + nom (colonne unique dans notre schéma)
ville,
age
FROM visiteur
WHERE ville = 'Lyon'
AND age > 30
ORDER BY nom ASC;
Flag D1
Investigation
Sans l'afficher, filtre : « le nom des visiteurs dont l'email contient gsb.fr » — mais ta requête ne doit montrer que la colonne nom (donc email est dans le WHERE, pas dans le SELECT). Rends : ta requête + explique en une phrase pourquoi c'est possible.
12. Entraînement express
Avant le mini-projet, on muscle l'écriture. Pour chaque question, écris la requête, prédis le résultat, puis exécute pour vérifier. Tout se joue sur la table visiteur du chapitre 1.
D'abord, sais-tu lire une requête ?
Associe mentalement chaque requête à ce qu'elle renvoie (réponds dans ta tête, puis exécute pour confirmer) :
| # | Requête | Renvoie… |
|---|---|---|
| a | SELECT nom FROM visiteur WHERE age < 30; | ? |
| b | SELECT ville FROM visiteur WHERE nom LIKE 'K%'; | ? |
| c | SELECT * FROM visiteur ORDER BY age ASC LIMIT 1; | ? |
Ensuite, à toi d'écrire
- Le nom et la ville de tous les visiteurs.
- Les visiteurs de 40 ans ou plus (nom + âge).
- Les visiteurs qui ne sont pas de Paris.
- Les visiteurs dont le nom finit par « n » (LIKE).
- Les visiteurs de Lyon, triés par âge décroissant.
- Les 2 plus jeunes visiteurs (ORDER BY + LIMIT).
Flag B11
Entraînement (production)
Écris et exécute les 6 requêtes ci-dessus.
Rends : tes 6 requêtes et, pour chacune, le résultat obtenu (ou son nombre de lignes).
13. Mini-projet : réponds en SQL
On joue l'analyste de données GSB : traduire des questions métier en requêtes SQL. Ajoute une table frais (montants des notes de frais des visiteurs) :
CREATE TABLE frais (id INT, id_visiteur INT, montant DECIMAL, type TEXT);
INSERT INTO frais VALUES
(1,1,45.50,'Restaurant'),(2,1,120.00,'Hôtel'),
(3,3,12.00,'Transport'),(4,2,89.90,'Hôtel'),(5,3,60.00,'Restaurant');
Exemple travaillé (pour te lancer)
« Les frais d'hôtel, du plus cher au moins cher » se traduit ainsi :
SELECT type, montant FROM frais
WHERE type = 'Hôtel'
ORDER BY montant DESC;
Anticiper : SQL depuis C# (projet GSB Ordonnances)
Dans le projet GSB Ordonnances, le SQL sera exécuté depuis du code C#. Un piège de sécurité majeur guette si on colle une valeur saisie par l'utilisateur directement dans la requête :
// DANGEREUX — concaténation directe (NE PAS FAIRE)
string ville = textBoxVille.Text; // ex : Lyon' OR '1'='1
string sql = "SELECT * FROM visiteur WHERE ville = '" + ville + "'";
// Requête résultante :
// SELECT * FROM visiteur WHERE ville = 'Lyon' OR '1'='1'
// → TOUTES les lignes renvoyées, filtre neutralisé !
// SÉCURISÉ — paramètre nommé (toujours utiliser ça)
string sql = "SELECT * FROM visiteur WHERE ville = @ville";
using var cmd = new MySqlCommand(sql, connection);
cmd.Parameters.AddWithValue("@ville", textBoxVille.Text);
// La valeur transite séparément : jamais interprétée comme code SQL
À toi de jouer pour les suivantes — même méthode : repère le filtre (WHERE), les colonnes (SELECT), le tri éventuel (ORDER BY).
Les questions à traduire en SQL
- Tous les frais de plus de 50 € (montant + type).
- Les frais de type « Restaurant ».
- Les frais du visiteur n°3 (
id_visiteur = 3). - Les frais de type « Restaurant » ET de plus de 50 €.
- Les types de frais distincts.
- Tous les frais triés du plus cher au moins cher.
- Le frais le plus cher (un seul, avec ORDER BY + LIMIT).
Flag B12
Mini-projet (production)
Écris les 7 requêtes et exécute-les.
Rends : tes 7 requêtes et, pour chacune, le nombre de lignes du résultat. C'est exactement ce que tu feras sur la base de GLPI dans le projet AP.
Flag E1
Extension
Bonus A : les frais entre 40 et 100 € (BETWEEN), triés du plus cher au moins cher.
Bonus B : les frais dont le type contient « stau » (LIKE) — affiche la colonne montant sous l'en-tête cout (AS).
Rends : tes 2 requêtes et leurs résultats.
Pour finir
Ton antisèche (la requête SELECT)
SELECT colonnes -- quoi afficher (* = tout, AS = renommer)
FROM table -- d'où
WHERE condition -- filtrer les lignes (IS NULL pour l'absence)
ORDER BY colonne -- trier (ASC / DESC)
LIMIT n; -- limiter (ORDER BY + LIMIT = top N)
| Je veux… | SQL |
|---|---|
| filtrer un texte exact | WHERE ville = 'Lyon' |
| comparer un nombre | WHERE age > 30 |
| un intervalle / une liste | BETWEEN 30 AND 40 · IN ('Lyon','Paris') |
| une valeur absente | WHERE email IS NULL |
| chercher dans du texte | WHERE nom LIKE '%a%' |
| plusieurs conditions | AND / OR / NOT |
| renommer une colonne | SELECT nom AS visiteur |
| sans doublons / top N | DISTINCT … · ORDER BY … LIMIT n |
Vérifie tes acquis
- À quoi servent
SELECTetFROM? - Que fait
WHERE? Dans quel ordre la base lit-elleFROM,WHERE,SELECT? - Comment écrit-on une valeur texte dans une condition ? Et un nombre ?
- Comment retrouver les lignes où une valeur est absente (et pourquoi pas
= NULL) ? - À quoi sert
LIKEet le symbole%? - Différence entre
ANDetOR? À quoi sertAS? - Comment obtenir un « top 3 » des plus chers ?
Corrigé du quiz (auto-vérification)
Voir le corrigéMasquer le corrigé
- SELECT choisit les colonnes à afficher ; FROM désigne la table source. Ordre d'exécution réel : FROM → WHERE → SELECT (pas l'ordre d'écriture).
- WHERE filtre les lignes : seules celles où la condition vaut TRUE sont conservées. La base exécute FROM, puis WHERE, puis SELECT — dans cet ordre.
- Une valeur texte va entre guillemets simples :
'Lyon'. Un nombre s'écrit sans guillemets :34. Les guillemets doubles entourent un nom de colonne ou de table. - On utilise
IS NULL(jamais= NULL) : NULL signifie « inconnu », etinconnu = inconnuretourne UNKNOWN, jamais TRUE.IS NULLteste l'absence sans comparer de valeur. LIKEcherche un motif dans du texte.%remplace n'importe quelle séquence (0 caractère ou plus)._remplace exactement 1 caractère. Ex. :'M_rc%'trouve « Marc Dupont ».AND: les deux conditions doivent être vraies simultanément.OR: au moins l'une des deux suffit.ASrenomme une colonne dans le résultat (alias d'affichage uniquement — la table n'est pas modifiée).SELECT col FROM table ORDER BY col DESC LIMIT 3;— on trie du plus cher au moins cher (DESC), puisLIMIT 3garde les 3 premières lignes du résultat trié.
Glossaire
| Mot | Définition |
|---|---|
| SQL | le langage d'interrogation des bases de données |
| Requête | une question écrite en SQL |
| SELECT … FROM | choisir des colonnes dans une table |
| WHERE | filtrer les lignes selon une condition |
| = / <> / < / > / BETWEEN / IN | opérateurs de comparaison |
| NULL / IS NULL | valeur absente / la tester |
| LIKE / % | rechercher un motif dans du texte |
| AND / OR / NOT | combiner des conditions |
| AS | renommer une colonne dans le résultat |
| DISTINCT | supprimer les doublons du résultat |
| ORDER BY / LIMIT | trier / limiter le nombre de lignes |
| -- … /* … */ | commentaires (ignorés par la base) |