2026-06-15 11:28:37 +02:00
# Cours : Le langage SQL
2024-12-11 10:28:06 +01:00
2026-06-15 11:28:37 +02:00
---
2024-12-11 10:28:06 +01:00
2026-06-15 11:28:37 +02:00
## 1. Introduction
2024-12-11 10:28:06 +01:00
2026-06-15 11:28:37 +02:00
### 1.1. Historique
2024-12-11 10:28:06 +01:00
2026-06-15 11:28:37 +02:00
**SQL** (*Structured Query Language*) est un langage de requêtes créé en 1974 par IBM, puis normalisé en 1986. Il permet d'interagir avec les **bases de données relationnelles** .
2024-12-11 10:28:06 +01:00
2026-06-15 11:28:37 +02:00
SQL est aujourd'hui le standard universel pour :
- Créer et modifier la structure des bases de données
- Insérer, modifier et supprimer des données
- Interroger les données (requêtes)
2024-12-11 10:28:06 +01:00
2026-06-15 11:28:37 +02:00
### 1.2. Les SGBD
2024-12-11 10:28:06 +01:00
2026-06-15 11:28:37 +02:00
Un **SGBD** (*Système de Gestion de Base de Données*) est un logiciel qui permet de stocker, organiser et manipuler des données. Exemples :
2024-12-11 10:28:06 +01:00
2026-06-15 11:28:37 +02:00
| SGBD | Type | Utilisation |
|------|------|-------------|
| SQLite | Léger, fichier local | Applications mobiles, embarqué |
| MySQL / MariaDB | Serveur | Sites web, applications |
| PostgreSQL | Serveur avancé | Applications complexes |
| Oracle | Entreprise | Grandes entreprises |
| Microsoft SQL Server | Entreprise | Environnement Windows |
2024-12-11 10:28:06 +01:00
2026-06-15 11:28:37 +02:00
En NSI, nous utilisons principalement **SQLite** avec l'outil **DB Browser for SQLite** .
2024-12-11 10:28:06 +01:00
2026-06-15 11:28:37 +02:00
---
2024-12-11 10:28:06 +01:00
2026-06-15 11:28:37 +02:00
## 2. Structure d'une base de données
2024-12-11 10:28:06 +01:00
2026-06-15 11:28:37 +02:00
### 2.1. Tables, attributs et enregistrements
2024-12-11 10:28:06 +01:00
2026-06-15 11:28:37 +02:00
Une base de données relationnelle est composée de **tables** . Chaque table contient :
- Des **colonnes** (ou **attributs** ) : les caractéristiques des données
- Des **lignes** (ou **enregistrements** ) : les données elles-mêmes
2024-12-11 10:28:06 +01:00
2026-06-15 11:28:37 +02:00
**Exemple : Table LIVRES**
2024-12-11 10:28:06 +01:00
2026-06-15 11:28:37 +02:00
| id | titre | auteur | ann_publi | note |
|----|-------|--------|-----------|------|
| 1 | 1984 | Orwell | 1949 | 10 |
| 2 | Dune | Herbert | 1965 | 8 |
| 3 | Fondation | Asimov | 1951 | 9 |
2024-12-11 10:28:06 +01:00
2026-06-15 11:28:37 +02:00
### 2.2. Types de données
2024-12-11 10:28:06 +01:00
2026-06-15 11:28:37 +02:00
| Type SQL | Description | Exemple |
|----------|-------------|---------|
| `INT` ou `INTEGER` | Nombre entier | 42, -7, 2024 |
| `REAL` ou `FLOAT` | Nombre décimal | 3.14, -0.5 |
| `TEXT` ou `VARCHAR` | Chaîne de caractères | 'Bonjour', 'Alice' |
| `DATE` | Date | '2024-01-15' |
| `BOOLEAN` | Booléen | TRUE, FALSE |
2024-12-11 10:28:06 +01:00
2026-06-15 11:28:37 +02:00
### 2.3. Clés primaires et étrangères
2024-12-11 10:28:06 +01:00
2026-06-15 11:28:37 +02:00
- **Clé primaire** (`PRIMARY KEY` ) : Identifiant unique de chaque enregistrement
- **Clé étrangère** (`FOREIGN KEY` ) : Référence vers la clé primaire d'une autre table
2024-12-11 10:28:06 +01:00
2026-06-15 11:28:37 +02:00
```
Table AUTEURS Table LIVRES
+----+--------+ +----+--------+-----------+
| id | nom | | id | titre | id_auteur |
+----+--------+ +----+--------+-----------+
| 1 | Orwell |<─────────────────| 1 | 1984 | 1 |
| 2 | Asimov |<─────────────────| 2 | Robots | 2 |
+----+--------+ +----+--------+-----------+
PK PK FK
```
2024-12-11 10:28:06 +01:00
2026-06-15 11:28:37 +02:00
---
2024-12-11 10:28:06 +01:00
2026-06-15 11:28:37 +02:00
## 3. Création et modification de tables
2024-12-11 10:28:06 +01:00
2026-06-15 11:28:37 +02:00
### 3.1. Créer une table : CREATE TABLE
2024-12-11 10:28:06 +01:00
2026-06-15 11:28:37 +02:00
```sql
CREATE TABLE LIVRES (
id INTEGER PRIMARY KEY ,
titre TEXT ,
auteur TEXT ,
ann_publi INTEGER ,
note INTEGER
);
```
2024-12-11 10:50:33 +01:00
2026-06-15 11:28:37 +02:00
### 3.2. Créer une table avec clé étrangère
2024-12-11 10:50:33 +01:00
2026-06-15 11:28:37 +02:00
```sql
CREATE TABLE LIVRES (
id INTEGER PRIMARY KEY ,
titre TEXT ,
id_auteur INTEGER ,
ann_publi INTEGER ,
FOREIGN KEY ( id_auteur ) REFERENCES AUTEURS ( id )
);
```
2024-12-11 10:50:33 +01:00
2026-06-15 11:28:37 +02:00
### 3.3. Supprimer une table : DROP TABLE
2024-12-11 10:50:33 +01:00
2026-06-15 11:28:37 +02:00
```sql
DROP TABLE LIVRES ;
2024-12-11 10:50:33 +01:00
```
2026-06-15 11:28:37 +02:00
⚠️ **Attention** : Cette opération est irréversible !
### 3.4. Modifier une table : ALTER TABLE
```sql
-- Ajouter une colonne
ALTER TABLE LIVRES ADD COLUMN editeur TEXT ;
-- Supprimer une colonne (selon le SGBD)
ALTER TABLE LIVRES DROP COLUMN editeur ;
2024-12-11 10:50:33 +01:00
```
2026-06-15 11:28:37 +02:00
---
## 4. Manipulation des données
2024-12-11 10:50:33 +01:00
2026-06-15 11:28:37 +02:00
### 4.1. Insérer des données : INSERT INTO
2024-12-11 10:50:33 +01:00
```sql
2026-06-15 11:28:37 +02:00
-- Insérer un enregistrement
INSERT INTO LIVRES ( id , titre , auteur , ann_publi , note )
VALUES ( 1 , '1984' , 'Orwell' , 1949 , 10 );
-- Insérer plusieurs enregistrements
INSERT INTO LIVRES ( id , titre , auteur , ann_publi , note )
2024-12-11 10:50:33 +01:00
VALUES
2026-06-15 11:28:37 +02:00
( 2 , 'Dune' , 'Herbert' , 1965 , 8 ),
( 3 , 'Fondation' , 'Asimov' , 1951 , 9 );
2024-12-11 10:50:33 +01:00
```
2026-06-15 11:28:37 +02:00
### 4.2. Modifier des données : UPDATE
2024-12-11 10:50:33 +01:00
```sql
2026-06-15 11:28:37 +02:00
-- Modifier tous les enregistrements correspondant à la condition
UPDATE LIVRES
SET note = 10
WHERE auteur = 'Asimov' ;
-- Modifier plusieurs colonnes
UPDATE LIVRES
SET note = 9 , ann_publi = 1950
WHERE id = 3 ;
```
⚠️ **Attention** : Sans clause `WHERE` , tous les enregistrements seront modifiés !
### 4.3. Supprimer des données : DELETE
```sql
-- Supprimer les enregistrements correspondant à la condition
DELETE FROM LIVRES
WHERE ann_publi < 1950 ;
-- Supprimer tous les enregistrements (vider la table)
DELETE FROM LIVRES ;
```
⚠️ **Attention** : Sans clause `WHERE` , tous les enregistrements seront supprimés !
---
## 5. Requêtes de sélection : SELECT
### 5.1. Syntaxe de base
```sql
SELECT colonnes
FROM table
WHERE conditions
ORDER BY colonne [ ASC | DESC ];
```
### 5.2. Sélectionner des colonnes
```sql
-- Toutes les colonnes
SELECT * FROM LIVRES ;
-- Colonnes spécifiques
SELECT titre , auteur FROM LIVRES ;
-- Avec alias
SELECT titre AS "Titre du livre" , auteur AS "Écrivain"
FROM LIVRES ;
```
### 5.3. Filtrer avec WHERE
**Opérateurs de comparaison :**
| Opérateur | Signification |
|-----------|---------------|
| `=` | Égal à |
| `<>` ou `!=` | Différent de |
| `<` , `<=` | Inférieur (ou égal) |
| `>` , `>=` | Supérieur (ou égal) |
| `BETWEEN a AND b` | Entre a et b (inclus) |
| `IN (v1, v2, ...)` | Dans la liste |
| `LIKE` | Correspondance de motif |
| `IS NULL` | Est nul |
**Exemples :**
```sql
-- Égalité
SELECT * FROM LIVRES WHERE auteur = 'Asimov' ;
-- Comparaison
SELECT * FROM LIVRES WHERE ann_publi > 1960 ;
-- Entre deux valeurs
SELECT * FROM LIVRES WHERE ann_publi BETWEEN 1950 AND 1970 ;
-- Dans une liste
SELECT * FROM LIVRES WHERE auteur IN ( 'Asimov' , 'Bradbury' , 'K.Dick' );
-- Correspondance de motif (LIKE)
SELECT * FROM LIVRES WHERE titre LIKE '%Robot%' ;
-- % = n'importe quelle suite de caractères
-- _ = un seul caractère
-- Valeur nulle
SELECT * FROM LIVRES WHERE note IS NULL ;
```
### 5.4. Combiner les conditions : AND, OR, NOT
```sql
-- ET logique
SELECT * FROM LIVRES
WHERE auteur = 'Asimov' AND ann_publi > 1950 ;
-- OU logique
SELECT * FROM LIVRES
WHERE auteur = 'Asimov' OR auteur = 'Bradbury' ;
-- Négation
SELECT * FROM LIVRES
WHERE NOT auteur = 'Asimov' ;
-- Combinaison avec parenthèses
SELECT * FROM LIVRES
WHERE ( auteur = 'Asimov' OR auteur = 'Bradbury' ) AND note >= 8 ;
```
### 5.5. Trier les résultats : ORDER BY
```sql
-- Tri croissant (par défaut)
SELECT * FROM LIVRES ORDER BY ann_publi ;
SELECT * FROM LIVRES ORDER BY ann_publi ASC ;
-- Tri décroissant
SELECT * FROM LIVRES ORDER BY note DESC ;
-- Tri multiple
SELECT * FROM LIVRES ORDER BY auteur ASC , ann_publi DESC ;
```
### 5.6. Éliminer les doublons : DISTINCT
```sql
-- Liste des auteurs (sans doublons)
SELECT DISTINCT auteur FROM LIVRES ;
```
### 5.7. Limiter les résultats : LIMIT
```sql
-- Les 5 premiers résultats
SELECT * FROM LIVRES LIMIT 5 ;
-- Pagination : 5 résultats à partir du 10e
SELECT * FROM LIVRES LIMIT 5 OFFSET 10 ;
2024-12-11 10:50:33 +01:00
```
2026-06-15 11:28:37 +02:00
---
## 6. Fonctions d'agrégation
Les fonctions d'agrégation effectuent des calculs sur un ensemble de valeurs.
2024-12-11 10:50:33 +01:00
2026-06-15 11:28:37 +02:00
### 6.1. Les fonctions principales
2024-12-11 10:50:33 +01:00
2026-06-15 11:28:37 +02:00
| Fonction | Description |
|----------|-------------|
| `COUNT(*)` | Nombre d'enregistrements |
| `COUNT(colonne)` | Nombre de valeurs non nulles |
| `SUM(colonne)` | Somme des valeurs |
| `AVG(colonne)` | Moyenne des valeurs |
| `MIN(colonne)` | Valeur minimale |
| `MAX(colonne)` | Valeur maximale |
2024-12-11 10:50:33 +01:00
2026-06-15 11:28:37 +02:00
### 6.2. Exemples
```sql
-- Nombre total de livres
SELECT COUNT ( * ) FROM LIVRES ;
2024-12-11 10:50:33 +01:00
2026-06-15 11:28:37 +02:00
-- Nombre de livres par auteur
SELECT COUNT ( * ) FROM LIVRES WHERE auteur = 'Asimov' ;
2024-12-11 10:50:33 +01:00
2026-06-15 11:28:37 +02:00
-- Note moyenne
SELECT AVG ( note ) FROM LIVRES ;
2024-12-11 10:50:33 +01:00
2026-06-15 11:28:37 +02:00
-- Note minimale et maximale
SELECT MIN ( note ), MAX ( note ) FROM LIVRES ;
2024-12-11 10:50:33 +01:00
2026-06-15 11:28:37 +02:00
-- Somme des notes (peu utile ici, mais illustratif)
SELECT SUM ( note ) FROM LIVRES ;
2024-12-11 10:50:33 +01:00
2026-06-15 11:28:37 +02:00
-- Année du livre le plus ancien
SELECT MIN ( ann_publi ) FROM LIVRES ;
```
2024-12-11 10:50:33 +01:00
2026-06-15 11:28:37 +02:00
### 6.3. Regrouper les données : GROUP BY
2024-12-11 10:50:33 +01:00
2026-06-15 11:28:37 +02:00
`GROUP BY` permet de regrouper les enregistrements par valeur d'une colonne.
2024-12-11 10:50:33 +01:00
2026-06-15 11:28:37 +02:00
```sql
-- Nombre de livres par auteur
SELECT auteur , COUNT ( * ) AS nb_livres
FROM LIVRES
GROUP BY auteur ;
-- Note moyenne par auteur
SELECT auteur , AVG ( note ) AS note_moyenne
FROM LIVRES
GROUP BY auteur ;
-- Résultat :
-- +----------+--------------+
-- | auteur | note_moyenne |
-- +----------+--------------+
-- | Asimov | 8.67 |
-- | Bradbury | 7.50 |
-- | K.Dick | 8.33 |
-- +----------+--------------+
```
2024-12-11 10:50:33 +01:00
2026-06-15 11:28:37 +02:00
### 6.4. Filtrer les groupes : HAVING
2024-12-11 10:50:33 +01:00
2026-06-15 11:28:37 +02:00
`HAVING` filtre les résultats **après** le regroupement (contrairement à `WHERE` qui filtre **avant** ).
2024-12-11 10:50:33 +01:00
2026-06-15 11:28:37 +02:00
```sql
-- Auteurs ayant écrit plus de 2 livres
SELECT auteur , COUNT ( * ) AS nb_livres
FROM LIVRES
GROUP BY auteur
HAVING COUNT ( * ) > 2 ;
-- Auteurs avec une note moyenne >= 8
SELECT auteur , AVG ( note ) AS note_moyenne
FROM LIVRES
GROUP BY auteur
HAVING AVG ( note ) >= 8 ;
```
2024-12-11 10:50:33 +01:00
2026-06-15 11:28:37 +02:00
**Différence WHERE / HAVING :**
```sql
-- WHERE filtre les lignes AVANT le regroupement
SELECT auteur , AVG ( note )
FROM LIVRES
WHERE ann_publi > 1950 -- Filtre les livres publiés après 1950
GROUP BY auteur ;
-- HAVING filtre les groupes APRÈS le regroupement
SELECT auteur , AVG ( note )
FROM LIVRES
GROUP BY auteur
HAVING AVG ( note ) > 8 ; -- Garde les auteurs avec moyenne > 8
```
---
## 7. Jointures
Les jointures permettent de combiner des données provenant de plusieurs tables.
### 7.1. INNER JOIN (jointure interne)
Retourne uniquement les enregistrements qui ont une correspondance dans les deux tables.
```sql
SELECT LIVRES . titre , AUTEURS . nom , AUTEURS . prenom
FROM LIVRES
INNER JOIN AUTEURS ON LIVRES . id_auteur = AUTEURS . id ;
```
**Schéma :**
```
LIVRES AUTEURS Résultat INNER JOIN
+----+------+ +----+------+ +------+------+
| id | id_a | | id | nom | | titre| nom |
+----+------+ +----+------+ +------+------+
| 1 | 1 | | 1 | Orwell| | 1984 | Orwell|
| 2 | 2 | | 2 | Asimov| | Fond.| Asimov|
| 3 | NULL | | 3 | Dick | +------+------+
+----+------+ +----+------+ (le livre 3 est exclu car id_a est NULL)
```
### 7.2. LEFT JOIN (jointure externe gauche)
Retourne tous les enregistrements de la table de gauche, même sans correspondance.
```sql
SELECT LIVRES . titre , AUTEURS . nom
FROM LIVRES
LEFT JOIN AUTEURS ON LIVRES . id_auteur = AUTEURS . id ;
```
### 7.3. Alias de tables
Pour simplifier l'écriture :
```sql
SELECT L . titre , A . nom , A . prenom
FROM LIVRES L
INNER JOIN AUTEURS A ON L . id_auteur = A . id
WHERE A . langue_ecriture = 'français' ;
```
### 7.4. Jointures multiples
```sql
SELECT L . titre , A . nom , E . nom_editeur
FROM LIVRES L
INNER JOIN AUTEURS A ON L . id_auteur = A . id
INNER JOIN EDITEURS E ON L . id_editeur = E . id ;
```
---
## 8. Ordre d'exécution des clauses
L'ordre d'écriture et l'ordre d'exécution sont différents :
**Ordre d'écriture :**
```sql
SELECT ... FROM ... WHERE ... GROUP BY ... HAVING ... ORDER BY ... LIMIT ...
```
**Ordre d'exécution :**
1. `FROM` et `JOIN` : Sélection des tables
2. `WHERE` : Filtrage des lignes
3. `GROUP BY` : Regroupement
4. `HAVING` : Filtrage des groupes
5. `SELECT` : Sélection des colonnes
6. `DISTINCT` : Élimination des doublons
7. `ORDER BY` : Tri
8. `LIMIT` : Limitation du nombre de résultats
---
## 9. Bonnes pratiques
### 9.1. Conventions d'écriture
- Mots-clés SQL en **MAJUSCULES** : `SELECT` , `FROM` , `WHERE`
- Noms de tables en **MAJUSCULES** : `LIVRES` , `AUTEURS`
- Noms de colonnes en **minuscules** : `titre` , `auteur`
- Indentation pour la lisibilité
```sql
SELECT L . titre ,
A . nom ,
A . prenom
FROM LIVRES L
INNER JOIN AUTEURS A ON L . id_auteur = A . id
WHERE A . langue_ecriture = 'français'
AND L . ann_publi > 1950
ORDER BY L . ann_publi DESC ;
```
### 9.2. Sécurité : Injections SQL
⚠️ Ne jamais construire des requêtes SQL par concaténation de chaînes avec des entrées utilisateur !
```python
# DANGEREUX - Injection SQL possible
requete = "SELECT * FROM USERS WHERE nom = '" + nom_utilisateur + "'"
# SÉCURISÉ - Requête paramétrée
cursor . execute ( "SELECT * FROM USERS WHERE nom = ?" , ( nom_utilisateur ,))
```
---
## 10. Synthèse
```
┌─────────────────────────────────────────────────────────────────┐
│ REQUÊTE SQL │
├─────────────────────────────────────────────────────────────────┤
│ SELECT [DISTINCT] colonnes, AGG(colonne) │
│ FROM table1 │
│ [INNER|LEFT] JOIN table2 ON condition │
│ WHERE conditions │
│ GROUP BY colonne │
│ HAVING condition_agregation │
│ ORDER BY colonne [ASC|DESC] │
│ LIMIT n [OFFSET m] │
└─────────────────────────────────────────────────────────────────┘
┌──────────────┬────────────────────────────────────────────────┐
│ Commande │ Action │
├──────────────┼────────────────────────────────────────────────┤
│ CREATE TABLE │ Créer une table │
│ DROP TABLE │ Supprimer une table │
│ INSERT INTO │ Insérer des données │
│ UPDATE │ Modifier des données │
│ DELETE │ Supprimer des données │
│ SELECT │ Interroger des données │
└──────────────┴────────────────────────────────────────────────┘
┌──────────────┬────────────────────────────────────────────────┐
│ Agrégation │ Description │
├──────────────┼────────────────────────────────────────────────┤
│ COUNT(*) │ Nombre d'enregistrements │
│ SUM(col) │ Somme │
│ AVG(col) │ Moyenne │
│ MIN(col) │ Minimum │
│ MAX(col) │ Maximum │
└──────────────┴────────────────────────────────────────────────┘
```
---
## Pour aller plus loin
- **SQL Murder Mystery** : Un jeu pour apprendre SQL en résolvant un meurtre
[https://mystery.knightlab.com ](https://mystery.knightlab.com )
- **SQLBolt** : Tutoriel interactif
[https://sqlbolt.com ](https://sqlbolt.com )
- **W3Schools SQL** : Référence complète
[https://www.w3schools.com/sql/ ](https://www.w3schools.com/sql/ )
2024-12-11 10:50:33 +01:00
2026-01-17 23:10:49 +01:00
---
Auteur : Florian Mathieu
2026-08-11 23:29:02 +02:00
Licence CC BY-SA
2026-01-17 23:10:49 +01:00
2026-08-11 23:29:02 +02:00
<a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/"><img alt="Licence Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-sa/4.0/88x31.png" /></a> <br />Ce cours est mis à disposition selon les termes de la <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 4.0 International</a>.