Aller au contenu

Partie 3 : Le langage SQL

Programme officiel (B.O.)

B.O. spécial n° 8 du 25 juillet 2019 - NSI Terminale

Contenus Capacités attendues Commentaires
Langage SQL : requêtes d'interrogation et de mise à jour d'une base de données. Identifier les composants d'une requête. Construire des requêtes d'interrogation à l'aide des clauses du langage SQL : SELECT, FROM, WHERE, JOIN. Construire des requêtes d'insertion et de mise à jour à l'aide de : UPDATE, INSERT, DELETE. On peut utiliser DISTINCT, ORDER BY ou les fonctions d'agrégation sans utiliser les clauses GROUP BY et HAVING.

1. Présentation du langage SQL

1.1 Qu'est-ce que SQL ?

SQL (Structured Query Language, langage de requêtes structurées) est le langage standard pour communiquer avec une base de données relationnelle. Il permet de :

  • interroger les données (lire) ;
  • insérer de nouvelles données ;
  • modifier des données existantes ;
  • supprimer des données ;
  • créer et modifier la structure des tables.

Repère historique

SQL a été conçu dans les années 1970 par Donald Chamberlin et Raymond Boyce chez IBM, à la suite des travaux de Codd sur le modèle relationnel. Il est devenu un standard international (norme ISO) en 1987.

1.2 Base de données exemple

Pour illustrer les requêtes, on utilisera la base de données suivante d'une médiathèque :

Table Livres :

id titre auteur_id annee genre
1 Les Misérables 1 1862 Roman
2 Notre-Dame de Paris 1 1831 Roman
3 Germinal 2 1885 Roman
4 Le Petit Prince 3 1943 Conte
5 Vol de nuit 3 1931 Roman
6 L'Étranger 4 1942 Roman

Table Auteurs :

id nom prenom nationalite
1 Hugo Victor Française
2 Zola Émile Française
3 Saint-Exupéry Antoine de Française
4 Camus Albert Française

Table Emprunts :

id livre_id adherent date_emprunt date_retour
1 1 Lucie 2025-09-01 2025-09-15
2 4 Marc 2025-09-03 NULL
3 3 Lucie 2025-09-10 2025-09-24
4 6 Sophie 2025-09-12 NULL
5 1 Marc 2025-09-20 NULL

2. Requêtes d'interrogation (SELECT)

2.1 Sélectionner des colonnes : SELECT ... FROM

La requête de base permet de choisir quelles colonnes afficher et dans quelle table.

SELECT titre, annee FROM Livres;
titre annee
Les Misérables 1862
Notre-Dame de Paris 1831
Germinal 1885
Le Petit Prince 1943
Vol de nuit 1931
L'Étranger 1942

Pour sélectionner toutes les colonnes, on utilise * :

SELECT * FROM Auteurs;

2.2 Filtrer les lignes : WHERE

La clause WHERE permet de ne garder que les lignes qui vérifient une condition.

SELECT titre, annee FROM Livres WHERE annee > 1900;
titre annee
Le Petit Prince 1943
Vol de nuit 1931
L'Étranger 1942

Opérateurs de comparaison :

Opérateur Signification
= Égal à
<> ou != Différent de
<, > Inférieur, supérieur
<=, >= Inférieur ou égal, supérieur ou égal
BETWEEN a AND b Compris entre a et b
LIKE Correspondance de motif (avec % et _)
IN (...) Appartient à un ensemble
IS NULL Est vide (NULL)
IS NOT NULL N'est pas vide

Combinaison de conditions avec AND, OR, NOT :

SELECT titre FROM Livres
WHERE genre = 'Roman' AND annee >= 1880;
titre
Germinal
L'Étranger

Recherche avec motif :

SELECT titre FROM Livres WHERE titre LIKE 'Le%';
titre
Les Misérables
Le Petit Prince

Le % remplace n'importe quelle suite de caractères ; le _ remplace un seul caractère.

2.3 Éliminer les doublons : DISTINCT

SELECT DISTINCT genre FROM Livres;
genre
Roman
Conte

2.4 Trier les résultats : ORDER BY

SELECT titre, annee FROM Livres ORDER BY annee;
titre annee
Notre-Dame de Paris 1831
Les Misérables 1862
Germinal 1885
Vol de nuit 1931
L'Étranger 1942
Le Petit Prince 1943

Par défaut, le tri est croissant (ASC). Pour un tri décroissant, on ajoute DESC :

SELECT titre, annee FROM Livres ORDER BY annee DESC;

2.5 Fonctions d'agrégation

Les fonctions d'agrégation effectuent un calcul sur un ensemble de valeurs et renvoient une seule valeur.

Fonction Description
COUNT(*) Nombre de lignes
COUNT(attribut) Nombre de valeurs non NULL
SUM(attribut) Somme
AVG(attribut) Moyenne
MIN(attribut) Valeur minimale
MAX(attribut) Valeur maximale
SELECT COUNT(*) FROM Livres;

→ Résultat : 6 (il y a 6 livres)

SELECT MIN(annee), MAX(annee) FROM Livres;

→ Résultat : 1831, 1943

SELECT COUNT(*) FROM Livres WHERE genre = 'Roman';

→ Résultat : 5


3. Requêtes sur plusieurs tables : JOIN

3.1 Le problème

On veut afficher le titre de chaque livre avec le nom de son auteur. Or, ces informations sont dans deux tables différentes (Livres et Auteurs), reliées par auteur_id / id.

3.2 La jointure (JOIN)

La clause JOIN permet de combiner les lignes de deux tables en se basant sur une condition de correspondance.

SELECT Livres.titre, Auteurs.nom, Auteurs.prenom
FROM Livres
JOIN Auteurs ON Livres.auteur_id = Auteurs.id;
titre nom prenom
Les Misérables Hugo Victor
Notre-Dame de Paris Hugo Victor
Germinal Zola Émile
Le Petit Prince Saint-Exupéry Antoine de
Vol de nuit Saint-Exupéry Antoine de
L'Étranger Camus Albert

Préfixer les attributs

Quand deux tables ont des attributs de même nom (ici id), on préfixe avec le nom de la table : Livres.id, Auteurs.id.

3.3 Jointure avec filtre

On peut combiner JOIN et WHERE :

SELECT Livres.titre, Auteurs.nom
FROM Livres
JOIN Auteurs ON Livres.auteur_id = Auteurs.id
WHERE Auteurs.nom = 'Hugo';
titre nom
Les Misérables Hugo
Notre-Dame de Paris Hugo

3.4 Jointure de trois tables

On peut enchaîner plusieurs JOIN :

SELECT Emprunts.adherent, Livres.titre, Auteurs.nom
FROM Emprunts
JOIN Livres ON Emprunts.livre_id = Livres.id
JOIN Auteurs ON Livres.auteur_id = Auteurs.id
WHERE Emprunts.date_retour IS NULL;
adherent titre nom
Marc Le Petit Prince Saint-Exupéry
Sophie L'Étranger Camus
Marc Les Misérables Hugo

Cette requête affiche les emprunts en cours (non rendus).


4. Requêtes de mise à jour

4.1 Insérer des données : INSERT INTO

INSERT INTO Auteurs (id, nom, prenom, nationalite)
VALUES (5, 'Dumas', 'Alexandre', 'Française');

Pour insérer plusieurs lignes :

INSERT INTO Livres (id, titre, auteur_id, annee, genre) VALUES
    (7, 'Les Trois Mousquetaires', 5, 1844, 'Roman'),
    (8, 'Le Comte de Monte-Cristo', 5, 1844, 'Roman');

4.2 Modifier des données : UPDATE

UPDATE Emprunts
SET date_retour = '2025-10-01'
WHERE id = 2;

Cette requête enregistre le retour du livre emprunté par Marc (emprunt n° 2).

Attention au WHERE

Un UPDATE sans WHERE modifie toutes les lignes de la table. Il faut toujours vérifier la condition avant d'exécuter.

4.3 Supprimer des données : DELETE

DELETE FROM Emprunts WHERE id = 1;

Supprime l'emprunt n° 1 (celui de Lucie, déjà rendu).

Attention au WHERE

Un DELETE sans WHERE supprime toutes les lignes de la table. C'est irréversible.


5. Structure d'une requête SQL

5.1 Ordre des clauses

Une requête SELECT complète suit cet ordre :

SELECT colonnes          -- 1. Quelles colonnes afficher
FROM table               -- 2. Dans quelle(s) table(s)
JOIN table2 ON condition -- 3. Jointure (optionnel)
WHERE condition          -- 4. Filtre sur les lignes (optionnel)
ORDER BY colonne         -- 5. Tri (optionnel)

5.2 Récapitulatif des mots-clés

Mot-clé Rôle Type de requête
SELECT Choisir les colonnes à afficher Interrogation
FROM Indiquer la table source Interrogation
WHERE Filtrer selon une condition Interrogation / Mise à jour
JOIN ... ON Combiner deux tables Interrogation
DISTINCT Éliminer les doublons Interrogation
ORDER BY Trier les résultats Interrogation
COUNT, SUM, AVG, MIN, MAX Fonctions d'agrégation Interrogation
INSERT INTO ... VALUES Ajouter des enregistrements Mise à jour
UPDATE ... SET Modifier des enregistrements Mise à jour
DELETE FROM Supprimer des enregistrements Mise à jour

6. SQL et Python

On peut exécuter des requêtes SQL depuis Python avec le module sqlite3 :

import sqlite3

connexion = sqlite3.connect("mediatheque.db")
curseur = connexion.cursor()

curseur.execute("""
    SELECT Livres.titre, Auteurs.nom
    FROM Livres
    JOIN Auteurs ON Livres.auteur_id = Auteurs.id
    WHERE Livres.annee > 1900
    ORDER BY Livres.annee
""")

for titre, nom in curseur.fetchall():
    print(f"{titre} ({nom})")

connexion.close()
Vol de nuit (Saint-Exupéry)
L'Étranger (Camus)
Le Petit Prince (Saint-Exupéry)

Injection SQL

Ne jamais insérer directement des valeurs utilisateur dans une requête SQL (risque d'injection SQL). Utiliser les paramètres avec ? :

# MAUVAIS (vulnérable) :
curseur.execute(f"SELECT * FROM Eleves WHERE nom = '{nom_saisi}'")

# BON (sécurisé) :
curseur.execute("SELECT * FROM Eleves WHERE nom = ?", (nom_saisi,))


À retenir

Opération Syntaxe SQL
Lire toutes les colonnes SELECT * FROM table
Lire certaines colonnes SELECT col1, col2 FROM table
Filtrer SELECT ... FROM ... WHERE condition
Sans doublons SELECT DISTINCT col FROM table
Trier SELECT ... ORDER BY col ASC/DESC
Compter SELECT COUNT(*) FROM table
Joindre deux tables SELECT ... FROM t1 JOIN t2 ON t1.cle = t2.cle
Insérer INSERT INTO table (cols) VALUES (vals)
Modifier UPDATE table SET col = val WHERE condition
Supprimer DELETE FROM table WHERE condition