Aller au contenu
Réussir mon BTS SIO

Tape une notion, une commande ou le nom d'une épreuve.

Par exemple

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 … FROMchoisir les colonnes et la table à lire
WHEREfiltrer : ne garder que certaines lignes
opérateurscomparer (=, <, >, BETWEEN…)
LIKErechercher dans du texte
AND / ORcombiner 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 :

Schéma : Table visiteur · 4 lignes en base · Requête SELECT · …WHERE ville='Lyon' · Résultat · 2 lignes filtrées · tu interroges · la base répond

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.

MotDéfinition
Requêteune question écrite en SQL
SELECTle mot-clé pour lire des données
Résultatle 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.

0 sur 15 dans cette étape

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.

idnomvilleageemail
1Marc DupontLyon34marc.dupont@gsb.fr
2Sophie MartinParis28sophie.martin@gsb.fr
3Karim BenaliLyon45(vide)
4Léa RouxLille31lea.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.

0 sur 15 dans cette étape

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.

0 sur 15 dans cette étape

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.

0 sur 15 dans cette étape

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.

0 sur 15 dans cette étape

5. Comparer : les opérateurs

Avec WHERE, on ne fait pas que tester l'égalité. On compare.

OpérateurSensExemple
=égalage = 34
<> ou !=différentville <> 'Lyon'
< > <= >=inférieur / supérieurage > 30
BETWEEN … AND …dans un intervalleage BETWEEN 30 AND 40
IN (…)dans une listeville 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 :

TypeCe qu'il stockePlage / tailleUsage typique
INTentier signé 32 bits−2 147 483 648 → 2 147 483 647id, age, quantité
BIGINTentier signé 64 bits±9 × 10¹⁸compteur de clics, clé sur grande table
DECIMAL(p,d)nombre exact à virgulep = chiffres totaux, d = après virguleDECIMAL(10,2) → montants GSB
FLOAT / DOUBLEnombre approché (IEEE 754)~7 / ~15 chiffres significatifsjamais pour l'argent (0,1 + 0,2 ≠ 0,3 en binaire)
VARCHAR(n)texte longueur variable1 à n caractères (max 65 535 en MySQL)VARCHAR(100) pour un nom
TEXTtexte longjusqu'à 65 535 octets en MySQLdescription, commentaire libre
DATEdate seule (sans heure)format ISO : YYYY-MM-DD'2025-01-15'
DATETIMEdate + heureYYYY-MM-DD HH:MM:SShorodatage 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.

0 sur 15 dans cette étape

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).

ExpressionRésultatPourquoi
NULL = NULLUNKNOWN« inconnu = inconnu » n'est pas prouvable
NULL = 'Lyon'UNKNOWNla valeur est peut-être différente, on ne sait pas
NULL IS NULLTRUEIS NULL teste l'absence, pas la valeur
NULL + 5NULLtoute opération arithmétique avec NULL donne NULL
NULL OR TRUETRUEexception : vrai quoi qu'il en soit de l'inconnu
NULL AND FALSEFALSEexception : 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 ?).

0 sur 15 dans cette étape

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%';
MotifTrouve…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.

0 sur 15 dans cette étape

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.

0 sur 15 dans cette étape

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).

0 sur 15 dans cette étape

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.

0 sur 15 dans cette étape

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.

Schéma : FROM · WHERE · SELECT · ORDER BY · LIMIT · prend la table · filtre les lignes · choisit colonnes · trie · coupe

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 :

ÉtapeClauseCe qu'elle faitAlias utilisable ?
1FROMouvre la table (ou la jointure)non
2WHEREfiltre les lignes avant tout calculnon
3GROUP BYgroupe les lignes par valeur de colonnenon (MySQL l'accepte par extension)
4HAVINGfiltre les groupes après agrégatnon
5SELECTchoisit colonnes, calcule, renomme (AS)c'est ici qu'ils naissent
6ORDER BYtrie le résultat finaloui (exception tolérée)
7LIMITcoupe à N lignesoui

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.

0 sur 15 dans cette étape

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êteRenvoie…
aSELECT nom FROM visiteur WHERE age < 30;?
bSELECT ville FROM visiteur WHERE nom LIKE 'K%';?
cSELECT * FROM visiteur ORDER BY age ASC LIMIT 1;?

Ensuite, à toi d'écrire

  1. Le nom et la ville de tous les visiteurs.
  2. Les visiteurs de 40 ans ou plus (nom + âge).
  3. Les visiteurs qui ne sont pas de Paris.
  4. Les visiteurs dont le nom finit par « n » (LIKE).
  5. Les visiteurs de Lyon, triés par âge décroissant.
  6. 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).

0 sur 15 dans cette étape

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

  1. Tous les frais de plus de 50 € (montant + type).
  2. Les frais de type « Restaurant ».
  3. Les frais du visiteur n°3 (id_visiteur = 3).
  4. Les frais de type « Restaurant » ET de plus de 50 €.
  5. Les types de frais distincts.
  6. Tous les frais triés du plus cher au moins cher.
  7. 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.

0 sur 15 dans cette étape

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.

0 sur 15 dans cette étape

Pour finir

Ton antisèche (la requête SELECT)

Ce que tu dois voir
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 exactWHERE ville = 'Lyon'
comparer un nombreWHERE age > 30
un intervalle / une listeBETWEEN 30 AND 40 · IN ('Lyon','Paris')
une valeur absenteWHERE email IS NULL
chercher dans du texteWHERE nom LIKE '%a%'
plusieurs conditionsAND / OR / NOT
renommer une colonneSELECT nom AS visiteur
sans doublons / top NDISTINCT … · ORDER BY … LIMIT n

Vérifie tes acquis

  1. À quoi servent SELECT et FROM ?
  2. Que fait WHERE ? Dans quel ordre la base lit-elle FROM, WHERE, SELECT ?
  3. Comment écrit-on une valeur texte dans une condition ? Et un nombre ?
  4. Comment retrouver les lignes où une valeur est absente (et pourquoi pas = NULL) ?
  5. À quoi sert LIKE et le symbole % ?
  6. Différence entre AND et OR ? À quoi sert AS ?
  7. Comment obtenir un « top 3 » des plus chers ?

Corrigé du quiz (auto-vérification)

Voir le corrigéMasquer le corrigé
  1. 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).
  2. 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.
  3. 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.
  4. On utilise IS NULL (jamais = NULL) : NULL signifie « inconnu », et inconnu = inconnu retourne UNKNOWN, jamais TRUE. IS NULL teste l'absence sans comparer de valeur.
  5. LIKE cherche 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 ».
  6. AND : les deux conditions doivent être vraies simultanément. OR : au moins l'une des deux suffit. AS renomme une colonne dans le résultat (alias d'affichage uniquement — la table n'est pas modifiée).
  7. SELECT col FROM table ORDER BY col DESC LIMIT 3; — on trie du plus cher au moins cher (DESC), puis LIMIT 3 garde les 3 premières lignes du résultat trié.

Glossaire

MotDéfinition
SQLle langage d'interrogation des bases de données
Requêteune question écrite en SQL
SELECT … FROMchoisir des colonnes dans une table
WHEREfiltrer les lignes selon une condition
= / <> / < / > / BETWEEN / INopérateurs de comparaison
NULL / IS NULLvaleur absente / la tester
LIKE / %rechercher un motif dans du texte
AND / OR / NOTcombiner des conditions
ASrenommer une colonne dans le résultat
DISTINCTsupprimer les doublons du résultat
ORDER BY / LIMITtrier / limiter le nombre de lignes
-- … /* … */commentaires (ignorés par la base)

Séance 1 terminé ?

Coche chaque livrable quand tu l'as : c'est la preuve que l'étape est acquise.

livrables
–
de série
–
Passer à la séance 2 : SQL (2) : filtrer, trier, compterVoir toutes les étapes du TP