Review cours Terminale NSI — POO, SQL, Sécurité, Soc, Calculabilité, Réseau
This commit is contained in:
554
SQL/Cours_SQL.md
554
SQL/Cours_SQL.md
@@ -1,554 +0,0 @@
|
||||
# Cours : Le langage SQL
|
||||
|
||||
---
|
||||
|
||||
## 1. Introduction
|
||||
|
||||
### 1.1. Historique
|
||||
|
||||
**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**.
|
||||
|
||||
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)
|
||||
|
||||
### 1.2. Les SGBD
|
||||
|
||||
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 :
|
||||
|
||||
| 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 |
|
||||
|
||||
En NSI, nous utilisons principalement **SQLite** avec l'outil **DB Browser for SQLite**.
|
||||
|
||||
---
|
||||
|
||||
## 2. Structure d'une base de données
|
||||
|
||||
### 2.1. Tables, attributs et enregistrements
|
||||
|
||||
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
|
||||
|
||||
**Exemple : Table LIVRES**
|
||||
|
||||
| id | titre | auteur | ann_publi | note |
|
||||
|----|-------|--------|-----------|------|
|
||||
| 1 | 1984 | Orwell | 1949 | 10 |
|
||||
| 2 | Dune | Herbert | 1965 | 8 |
|
||||
| 3 | Fondation | Asimov | 1951 | 9 |
|
||||
|
||||
### 2.2. Types de données
|
||||
|
||||
| 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 |
|
||||
|
||||
### 2.3. Clés primaires et étrangères
|
||||
|
||||
- **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
|
||||
|
||||
```
|
||||
Table AUTEURS Table LIVRES
|
||||
+----+--------+ +----+--------+-----------+
|
||||
| id | nom | | id | titre | id_auteur |
|
||||
+----+--------+ +----+--------+-----------+
|
||||
| 1 | Orwell |<─────────────────| 1 | 1984 | 1 |
|
||||
| 2 | Asimov |<─────────────────| 2 | Robots | 2 |
|
||||
+----+--------+ +----+--------+-----------+
|
||||
PK PK FK
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Création et modification de tables
|
||||
|
||||
### 3.1. Créer une table : CREATE TABLE
|
||||
|
||||
```sql
|
||||
CREATE TABLE LIVRES (
|
||||
id INTEGER PRIMARY KEY,
|
||||
titre TEXT,
|
||||
auteur TEXT,
|
||||
ann_publi INTEGER,
|
||||
note INTEGER
|
||||
);
|
||||
```
|
||||
|
||||
### 3.2. Créer une table avec clé étrangère
|
||||
|
||||
```sql
|
||||
CREATE TABLE LIVRES (
|
||||
id INTEGER PRIMARY KEY,
|
||||
titre TEXT,
|
||||
id_auteur INTEGER,
|
||||
ann_publi INTEGER,
|
||||
FOREIGN KEY (id_auteur) REFERENCES AUTEURS(id)
|
||||
);
|
||||
```
|
||||
|
||||
### 3.3. Supprimer une table : DROP TABLE
|
||||
|
||||
```sql
|
||||
DROP TABLE LIVRES;
|
||||
```
|
||||
|
||||
⚠️ **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;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Manipulation des données
|
||||
|
||||
### 4.1. Insérer des données : INSERT INTO
|
||||
|
||||
```sql
|
||||
-- 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)
|
||||
VALUES
|
||||
(2, 'Dune', 'Herbert', 1965, 8),
|
||||
(3, 'Fondation', 'Asimov', 1951, 9);
|
||||
```
|
||||
|
||||
### 4.2. Modifier des données : UPDATE
|
||||
|
||||
```sql
|
||||
-- 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;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Fonctions d'agrégation
|
||||
|
||||
Les fonctions d'agrégation effectuent des calculs sur un ensemble de valeurs.
|
||||
|
||||
### 6.1. Les fonctions principales
|
||||
|
||||
| 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 |
|
||||
|
||||
### 6.2. Exemples
|
||||
|
||||
```sql
|
||||
-- Nombre total de livres
|
||||
SELECT COUNT(*) FROM LIVRES;
|
||||
|
||||
-- Nombre de livres par auteur
|
||||
SELECT COUNT(*) FROM LIVRES WHERE auteur = 'Asimov';
|
||||
|
||||
-- Note moyenne
|
||||
SELECT AVG(note) FROM LIVRES;
|
||||
|
||||
-- Note minimale et maximale
|
||||
SELECT MIN(note), MAX(note) FROM LIVRES;
|
||||
|
||||
-- Somme des notes (peu utile ici, mais illustratif)
|
||||
SELECT SUM(note) FROM LIVRES;
|
||||
|
||||
-- Année du livre le plus ancien
|
||||
SELECT MIN(ann_publi) FROM LIVRES;
|
||||
```
|
||||
|
||||
### 6.3. Regrouper les données : GROUP BY
|
||||
|
||||
`GROUP BY` permet de regrouper les enregistrements par valeur d'une colonne.
|
||||
|
||||
```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 |
|
||||
-- +----------+--------------+
|
||||
```
|
||||
|
||||
### 6.4. Filtrer les groupes : HAVING
|
||||
|
||||
`HAVING` filtre les résultats **après** le regroupement (contrairement à `WHERE` qui filtre **avant**).
|
||||
|
||||
```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;
|
||||
```
|
||||
|
||||
**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/)
|
||||
|
||||
---
|
||||
|
||||
Auteur : Florian Mathieu
|
||||
|
||||
Licence CC BY NC
|
||||
|
||||
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="Licence Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-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-nc-sa/4.0/">Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International</a>.
|
||||
724
SQL/README.md
724
SQL/README.md
@@ -1,274 +1,549 @@
|
||||
# TP : Introduction au langage SQL avec DB Browser for SQLite
|
||||
# Cours : Le langage SQL
|
||||
|
||||
Ce TP vous guidera à travers la création et la manipulation d'une base de données en utilisant le logiciel **DB Browser for SQLite**. Vous apprendrez à créer des tables, insérer des données et exécuter des requêtes SQL pour interroger la base de données.
|
||||
---
|
||||
|
||||
> **Prérequis** : Avoir lu le cours [Cours_SQL.md](Cours_SQL.md) avant de commencer ce TP.
|
||||
## 1. Introduction
|
||||
|
||||
## Prérequis
|
||||
### 1.1. Historique
|
||||
|
||||
- Télécharger et installer [DB Browser for SQLite](https://sqlitebrowser.org/).
|
||||
**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**.
|
||||
|
||||
## Activité 3.1 : Création d'une base de données
|
||||
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)
|
||||
|
||||
1. **Lancer DB Browser for SQLite**. Vous devriez obtenir l'écran suivant :
|
||||
### 1.2. Les SGBD
|
||||
|
||||

|
||||
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 :
|
||||
|
||||
2. **Créer une nouvelle base de données** :
|
||||
|
||||
- Cliquez sur "Nouvelle base de données".
|
||||
- Nommez votre base de données, par exemple `db_livres.db`.
|
||||
- Vous verrez la fenêtre suivante :
|
||||
|
||||

|
||||
|
||||
- Cliquez sur "Annuler" pour fermer cette fenêtre.
|
||||
|
||||
3. **Vérifier la création de la base de données** :
|
||||
- Votre base de données est créée mais ne contient pas encore de tables.
|
||||
| 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 |
|
||||
|
||||

|
||||
En NSI, nous utilisons principalement **SQLite** avec l'outil **DB Browser for SQLite**.
|
||||
|
||||
## Activité 3.2 : Création d'une table
|
||||
---
|
||||
|
||||
1. **Accéder à l'onglet "Exécuter le SQL"** :
|
||||
|
||||
- Cliquez sur l'onglet "Exécuter le SQL".
|
||||
|
||||
2. **Créer la table `LIVRES`** :
|
||||
- Dans la fenêtre "SQL 1", saisissez la requête suivante :
|
||||
## 2. Structure d'une base de données
|
||||
|
||||
```sql
|
||||
CREATE TABLE LIVRES (
|
||||
id INT PRIMARY KEY,
|
||||
titre TEXT,
|
||||
auteur TEXT,
|
||||
ann_publi INT,
|
||||
note INT
|
||||
);
|
||||
```
|
||||
### 2.1. Tables, attributs et enregistrements
|
||||
|
||||
- Cliquez sur le bouton ▶ (ou appuyez sur F5) pour exécuter la requête.
|
||||
- Un message "Requête exécutée avec succès" devrait apparaître.
|
||||
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
|
||||
|
||||

|
||||
**Exemple : Table LIVRES**
|
||||
|
||||
## Activité 3.3 : Insertion de données
|
||||
| id | titre | auteur | ann_publi | note |
|
||||
|----|-------|--------|-----------|------|
|
||||
| 1 | 1984 | Orwell | 1949 | 10 |
|
||||
| 2 | Dune | Herbert | 1965 | 8 |
|
||||
| 3 | Fondation | Asimov | 1951 | 9 |
|
||||
|
||||
1. **Insérer des enregistrements dans la table `LIVRES`** :
|
||||
|
||||
- Toujours dans l'onglet "Exécuter le SQL", saisissez la requête suivante :
|
||||
|
||||
```sql
|
||||
INSERT INTO LIVRES (id, titre, auteur, ann_publi, note) VALUES
|
||||
(1, '1984', 'Orwell', 1949, 10),
|
||||
(2, 'Dune', 'Herbert', 1965, 8),
|
||||
(3, 'Fondation', 'Asimov', 1951, 9),
|
||||
(4, 'Le meilleur des mondes', 'Huxley', 1931, 7),
|
||||
(5, 'Fahrenheit 451', 'Bradbury', 1953, 7),
|
||||
(6, 'Ubik', 'K.Dick', 1969, 9),
|
||||
(7, 'Chroniques martiennes', 'Bradbury', 1950, 8),
|
||||
(8, 'La nuit des temps', 'Barjavel', 1968, 7),
|
||||
(9, 'Blade Runner', 'K.Dick', 1968, 8),
|
||||
(10, 'Les Robots', 'Asimov', 1950, 9),
|
||||
(11, 'La Planète des singes', 'Boulle', 1963, 8),
|
||||
(12, 'Ravage', 'Barjavel', 1943, 8),
|
||||
(13, 'Le Maître du Haut Château', 'K.Dick', 1962, 8),
|
||||
(14, 'Le monde des Ā', 'Van Vogt', 1945, 7),
|
||||
(15, 'La Fin de l’éternité', 'Asimov', 1955, 8),
|
||||
(16, 'De la Terre à la Lune', 'Verne', 1865, 10);
|
||||
```
|
||||
|
||||
- Exécutez la requête en cliquant sur le bouton ▶ ou en appuyant sur F5.
|
||||
- Un message de confirmation devrait apparaître.
|
||||
|
||||

|
||||
|
||||
2. **Vérifier les données insérées** :
|
||||
- Cliquez sur l'onglet "Parcourir les données" pour voir les enregistrements ajoutés.
|
||||
### 2.2. Types de données
|
||||
|
||||

|
||||
| 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 |
|
||||
|
||||
## Activité 3.4 : Exécution de requêtes SQL
|
||||
### 2.3. Clés primaires et étrangères
|
||||
|
||||
1. **Sélectionner tous les enregistrements** :
|
||||
- Dans l'onglet "Exécuter le SQL", saisissez la requête suivante :
|
||||
|
||||
```sql
|
||||
SELECT id, titre, auteur, ann_publi, note FROM LIVRES;
|
||||
```
|
||||
|
||||
- Exécutez la requête. Vous devriez obtenir tous les enregistrements de la table `LIVRES`.
|
||||
|
||||

|
||||
|
||||
2. **Sélectionner des colonnes spécifiques** :
|
||||
- Pour obtenir uniquement les titres et auteurs des livres, utilisez la requête :
|
||||
|
||||
```sql
|
||||
SELECT titre, auteur FROM LIVRES;
|
||||
```
|
||||
|
||||
3. **Filtrer les enregistrements** :
|
||||
- Pour obtenir les livres écrits par Asimov, utilisez :
|
||||
|
||||
```sql
|
||||
SELECT titre, ann_publi FROM LIVRES WHERE auteur = 'Asimov';
|
||||
```
|
||||
|
||||
4. **Combiner des conditions** :
|
||||
- Pour obtenir les livres d'Asimov publiés après 1953 :
|
||||
|
||||
```sql
|
||||
SELECT titre, ann_publi FROM LIVRES WHERE auteur = 'Asimov' AND ann_publi > 1953;
|
||||
```
|
||||
|
||||
5. **Trier les résultats** :
|
||||
- Pour trier les livres de K.Dick du plus ancien au plus récent :
|
||||
|
||||
```sql
|
||||
SELECT titre FROM LIVRES WHERE auteur = 'K.Dick' ORDER BY ann_publi;
|
||||
```
|
||||
|
||||
|
||||
|
||||
6. Écrivez et testez une requête permettant d'obtenir uniquement les titres des livres écrits par Philip K.Dick.
|
||||
|
||||
7. Saisissez et testez la requête SQL suivante :
|
||||
|
||||
```sql
|
||||
SELECT titre, ann_publi
|
||||
FROM LIVRES
|
||||
WHERE auteur='Asimov' AND ann_publi>1953
|
||||
```
|
||||
|
||||
Vérifiez que vous obtenez bien les livres écrits par Asimov publiés après 1953.
|
||||
|
||||
8. Écrivez une requête permettant d'obtenir les titres des livres publiés après 1945 qui ont une note supérieure ou égale à 9.
|
||||
|
||||
9. Écrivez une requête SQL permettant d'obtenir les livres de K.Dick classés du plus ancien au plus récent.
|
||||
|
||||
10. Créez une nouvelle base de données que vous nommerez par exemple db_livres_auteurs.db, puis créez une table AUTEURS à l'aide de la requête SQL suivante :
|
||||
|
||||
```sql
|
||||
CREATE TABLE AUTEURS
|
||||
(id INT, nom TEXT, prenom TEXT, ann_naissance INT, langue_ecriture TEXT, PRIMARY KEY (id));
|
||||
```
|
||||
|
||||
|
||||
Créez ensuite une deuxième table (LIVRES) :
|
||||
- **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
|
||||
|
||||
```
|
||||
CREATE TABLE LIVRES
|
||||
(id INT, titre TEXT, id_auteur INT, ann_publi INT, note INT, PRIMARY KEY (id), FOREIGN KEY (id_auteur) REFERENCES AUTEURS(id));
|
||||
Table AUTEURS Table LIVRES
|
||||
+----+--------+ +----+--------+-----------+
|
||||
| id | nom | | id | titre | id_auteur |
|
||||
+----+--------+ +----+--------+-----------+
|
||||
| 1 | Orwell |<─────────────────| 1 | 1984 | 1 |
|
||||
| 2 | Asimov |<─────────────────| 2 | Robots | 2 |
|
||||
+----+--------+ +----+--------+-----------+
|
||||
PK PK FK
|
||||
```
|
||||
|
||||
Comme vous l'avez sans doute remarqué nous avons précisé dans notre requête que l'attribut "id_auteur" jouera le rôle de clé étrangère : liaison entre "id_auteur" de la table LIVRES et "id" de la table AUTEURS (FOREIGN KEY (id_auteur) REFERENCES AUTEURS(id)).
|
||||
---
|
||||
|
||||
Ajoutez des données à la table AUTEURS à l'aide de la requête SQL suivante :
|
||||
## 3. Création et modification de tables
|
||||
|
||||
### 3.1. Créer une table : CREATE TABLE
|
||||
|
||||
```sql
|
||||
INSERT INTO AUTEURS
|
||||
(id,nom,prenom,ann_naissance,langue_ecriture)
|
||||
VALUES
|
||||
(1,'Orwell','George',1903,'anglais'),
|
||||
(2,'Herbert','Frank',1920,'anglais'),
|
||||
(3,'Asimov','Isaac',1920,'anglais'),
|
||||
(4,'Huxley','Aldous',1894,'anglais'),
|
||||
(5,'Bradbury','Ray',1920,'anglais'),
|
||||
(6,'K.Dick','Philip',1928,'anglais'),
|
||||
(7,'Barjavel','René',1911,'français'),
|
||||
(8,'Boulle','Pierre',1912,'français'),
|
||||
(9,'Van Vogt','Alfred Elton',1912,'anglais'),
|
||||
(10,'Verne','Jules',1828,'français');
|
||||
CREATE TABLE LIVRES (
|
||||
id INTEGER PRIMARY KEY,
|
||||
titre TEXT,
|
||||
auteur TEXT,
|
||||
ann_publi INTEGER,
|
||||
note INTEGER
|
||||
);
|
||||
```
|
||||
|
||||
Ajoutez des données à la table LIVRES à l'aide de la requête SQL suivante :
|
||||
### 3.2. Créer une table avec clé étrangère
|
||||
|
||||
```sql
|
||||
INSERT INTO LIVRES
|
||||
(id,titre,id_auteur,ann_publi,note)
|
||||
VALUES
|
||||
(1,'1984',1,1949,10),
|
||||
(2,'Dune',2,1965,8),
|
||||
(3,'Fondation',3,1951,9),
|
||||
(4,'Le meilleur des mondes',4,1931,7),
|
||||
(5,'Fahrenheit 451',5,1953,7),
|
||||
(6,'Ubik',6,1969,9),
|
||||
(7,'Chroniques martiennes',5,1950,8),
|
||||
(8,'La nuit des temps',7,1968,7),
|
||||
(9,'Blade Runner',6,1968,8),
|
||||
(10,'Les Robots',3,1950,9),
|
||||
(11,'La Planète des singes',8,1963,8),
|
||||
(12,'Ravage',7,1943,8),
|
||||
(13,'Le Maître du Haut Château',6,1962,8),
|
||||
(14,'Le monde des Ā',9,1945,7),
|
||||
(15,'La Fin de l’éternité',3,1955,8),
|
||||
(16,'De la Terre à la Lune',10,1865,10);
|
||||
CREATE TABLE LIVRES (
|
||||
id INTEGER PRIMARY KEY,
|
||||
titre TEXT,
|
||||
id_auteur INTEGER,
|
||||
ann_publi INTEGER,
|
||||
FOREIGN KEY (id_auteur) REFERENCES AUTEURS(id)
|
||||
);
|
||||
```
|
||||
|
||||
11. Saisissez et testez la requête SQL suivante :
|
||||
### 3.3. Supprimer une table : DROP TABLE
|
||||
|
||||
```sql
|
||||
SELECT titre,nom, prenom
|
||||
FROM LIVRES
|
||||
INNER JOIN AUTEURS ON LIVRES.id_auteur = AUTEURS.id
|
||||
```
|
||||
```sql
|
||||
DROP TABLE LIVRES;
|
||||
```
|
||||
|
||||
Rappel : attention, si un même nom d'attribut est présent dans les 2 tables (par exemple ici l'attribut id), il est nécessaire d'ajouter le nom de la table devant afin de pouvoir les distinguer (AUTEURS.id et LIVRES.id).
|
||||
⚠️ **Attention** : Cette opération est irréversible !
|
||||
|
||||
12. Écrivez une requête SQL permettant d'obtenir les titres des livres publiés après 1945 ainsi que le nom de leurs auteurs.
|
||||
### 3.4. Modifier une table : ALTER TABLE
|
||||
|
||||
13. Nous allons repartir avec une nouvelle base de données. Créez une nouvelle base de données nommée "db_livres.db".
|
||||
```sql
|
||||
-- Ajouter une colonne
|
||||
ALTER TABLE LIVRES ADD COLUMN editeur TEXT;
|
||||
|
||||
Créez ensuite une table LIVRES à l'aide de la requête suivante :
|
||||
-- Supprimer une colonne (selon le SGBD)
|
||||
ALTER TABLE LIVRES DROP COLUMN editeur;
|
||||
```
|
||||
|
||||
```sql
|
||||
CREATE TABLE LIVRES
|
||||
(id INT, titre TEXT, auteur TEXT, ann_publi INT, note INT, PRIMARY KEY (id));
|
||||
```
|
||||
---
|
||||
|
||||
Ajoutez des données à la table LIVRES à l'aide de la requête SQL suivante :
|
||||
## 4. Manipulation des données
|
||||
|
||||
```sql
|
||||
INSERT INTO LIVRES
|
||||
(id,titre,auteur,ann_publi,note)
|
||||
VALUES
|
||||
(1,'1984','Orwell',1949,10),
|
||||
(2,'Dune','Herbert',1965,8),
|
||||
(3,'Fondation','Asimov',1951,9),
|
||||
(4,'Le meilleur des mondes','Huxley',1931,7),
|
||||
(5,'Fahrenheit 451','Bradbury',1953,7),
|
||||
(6,'Ubik','K.Dick',1969,9),
|
||||
(7,'Chroniques martiennes','Bradbury',1950,8),
|
||||
(8,'La nuit des temps','Barjavel',1968,7),
|
||||
(9,'Blade Runner','K.Dick',1968,8),
|
||||
(10,'Les Robots','Asimov',1950,9),
|
||||
(11,'La Planète des singes','Boulle',1963,8),
|
||||
(12,'Ravage','Barjavel',1943,8),
|
||||
(13,'Le Maître du Haut Château','K.Dick',1962,8),
|
||||
(14,'Le monde des Ā','Van Vogt',1945,7),
|
||||
(15,'La Fin de l’éternité','Asimov',1955,8),
|
||||
(16,'De la Terre à la Lune','Verne',1865,10);
|
||||
```
|
||||
### 4.1. Insérer des données : INSERT INTO
|
||||
|
||||
14. À l'aide d'une requête SQL, ajoutez à la table LIVRES le livre suivant :
|
||||
- id : 17
|
||||
- titre : "2001 : L'Odyssée de l'espace"
|
||||
- auteur : "Clarke"
|
||||
- année de publication : 1968
|
||||
- note : 7
|
||||
```sql
|
||||
-- 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)
|
||||
VALUES
|
||||
(2, 'Dune', 'Herbert', 1965, 8),
|
||||
(3, 'Fondation', 'Asimov', 1951, 9);
|
||||
```
|
||||
|
||||
### 4.2. Modifier des données : UPDATE
|
||||
|
||||
15. Écrivez une requête permettant d'attribuer la note de 10 à tous les livres écrits par Asimov publiés après 1950. Testez cette requête.
|
||||
16. Écrivez une requête permettant de supprimer les livres publiés avant 1945. Testez cette requête.
|
||||
```sql
|
||||
-- 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;
|
||||
```
|
||||
|
||||
Source :
|
||||
⚠️ **Attention** : Sans clause `WHERE`, tous les enregistrements seront modifiés !
|
||||
|
||||
- [Pixees, site de David Roche](https://informatique-lycee.forge.apps.education.fr/terminale_nsi/cours-terminale/c3a/)
|
||||
### 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;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Fonctions d'agrégation
|
||||
|
||||
Les fonctions d'agrégation effectuent des calculs sur un ensemble de valeurs.
|
||||
|
||||
### 6.1. Les fonctions principales
|
||||
|
||||
| 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 |
|
||||
|
||||
### 6.2. Exemples
|
||||
|
||||
```sql
|
||||
-- Nombre total de livres
|
||||
SELECT COUNT(*) FROM LIVRES;
|
||||
|
||||
-- Nombre de livres par auteur
|
||||
SELECT COUNT(*) FROM LIVRES WHERE auteur = 'Asimov';
|
||||
|
||||
-- Note moyenne
|
||||
SELECT AVG(note) FROM LIVRES;
|
||||
|
||||
-- Note minimale et maximale
|
||||
SELECT MIN(note), MAX(note) FROM LIVRES;
|
||||
|
||||
-- Somme des notes (peu utile ici, mais illustratif)
|
||||
SELECT SUM(note) FROM LIVRES;
|
||||
|
||||
-- Année du livre le plus ancien
|
||||
SELECT MIN(ann_publi) FROM LIVRES;
|
||||
```
|
||||
|
||||
### 6.3. Regrouper les données : GROUP BY
|
||||
|
||||
`GROUP BY` permet de regrouper les enregistrements par valeur d'une colonne.
|
||||
|
||||
```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 |
|
||||
-- +----------+--------------+
|
||||
```
|
||||
|
||||
### 6.4. Filtrer les groupes : HAVING
|
||||
|
||||
`HAVING` filtre les résultats **après** le regroupement (contrairement à `WHERE` qui filtre **avant**).
|
||||
|
||||
```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;
|
||||
```
|
||||
|
||||
**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/)
|
||||
|
||||
---
|
||||
|
||||
@@ -277,4 +552,3 @@ Auteur : Florian Mathieu
|
||||
Licence CC BY NC
|
||||
|
||||
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="Licence Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-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-nc-sa/4.0/">Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International</a>.
|
||||
|
||||
|
||||
372
SQL/TP_SQLite.md
Normal file
372
SQL/TP_SQLite.md
Normal file
@@ -0,0 +1,372 @@
|
||||
# TP : Introduction au langage SQL avec DB Browser for SQLite
|
||||
|
||||
Ce TP vous guidera à travers la création et la manipulation d'une base de données en utilisant le logiciel **DB Browser for SQLite**. Vous apprendrez à créer des tables, insérer des données et exécuter des requêtes SQL pour interroger la base de données.
|
||||
|
||||
> **Prérequis** : Avoir lu le cours [README.md](README.md) avant de commencer ce TP.
|
||||
|
||||
## Prérequis
|
||||
|
||||
- Télécharger et installer [DB Browser for SQLite](https://sqlitebrowser.org/).
|
||||
|
||||
## Activité 3.1 : Création d'une base de données
|
||||
|
||||
1. **Lancer DB Browser for SQLite**. Vous devriez obtenir l'écran suivant :
|
||||
|
||||

|
||||
|
||||
2. **Créer une nouvelle base de données** :
|
||||
|
||||
- Cliquez sur "Nouvelle base de données".
|
||||
- Nommez votre base de données, par exemple `db_livres.db`.
|
||||
- Vous verrez la fenêtre suivante :
|
||||
|
||||

|
||||
|
||||
- Cliquez sur "Annuler" pour fermer cette fenêtre.
|
||||
|
||||
3. **Vérifier la création de la base de données** :
|
||||
- Votre base de données est créée mais ne contient pas encore de tables.
|
||||
|
||||

|
||||
|
||||
## Activité 3.2 : Création d'une table
|
||||
|
||||
1. **Accéder à l'onglet "Exécuter le SQL"** :
|
||||
|
||||
- Cliquez sur l'onglet "Exécuter le SQL".
|
||||
|
||||
2. **Créer la table `LIVRES`** :
|
||||
- Dans la fenêtre "SQL 1", saisissez la requête suivante :
|
||||
|
||||
```sql
|
||||
CREATE TABLE LIVRES (
|
||||
id INT PRIMARY KEY,
|
||||
titre TEXT,
|
||||
auteur TEXT,
|
||||
ann_publi INT,
|
||||
note INT
|
||||
);
|
||||
```
|
||||
|
||||
- Cliquez sur le bouton ▶ (ou appuyez sur F5) pour exécuter la requête.
|
||||
- Un message "Requête exécutée avec succès" devrait apparaître.
|
||||
|
||||

|
||||
|
||||
## Activité 3.3 : Insertion de données
|
||||
|
||||
1. **Insérer des enregistrements dans la table `LIVRES`** :
|
||||
|
||||
- Toujours dans l'onglet "Exécuter le SQL", saisissez la requête suivante :
|
||||
|
||||
```sql
|
||||
INSERT INTO LIVRES (id, titre, auteur, ann_publi, note) VALUES
|
||||
(1, '1984', 'Orwell', 1949, 10),
|
||||
(2, 'Dune', 'Herbert', 1965, 8),
|
||||
(3, 'Fondation', 'Asimov', 1951, 9),
|
||||
(4, 'Le meilleur des mondes', 'Huxley', 1931, 7),
|
||||
(5, 'Fahrenheit 451', 'Bradbury', 1953, 7),
|
||||
(6, 'Ubik', 'K.Dick', 1969, 9),
|
||||
(7, 'Chroniques martiennes', 'Bradbury', 1950, 8),
|
||||
(8, 'La nuit des temps', 'Barjavel', 1968, 7),
|
||||
(9, 'Blade Runner', 'K.Dick', 1968, 8),
|
||||
(10, 'Les Robots', 'Asimov', 1950, 9),
|
||||
(11, 'La Planète des singes', 'Boulle', 1963, 8),
|
||||
(12, 'Ravage', 'Barjavel', 1943, 8),
|
||||
(13, 'Le Maître du Haut Château', 'K.Dick', 1962, 8),
|
||||
(14, 'Le monde des Ā', 'Van Vogt', 1945, 7),
|
||||
(15, 'La Fin de l’éternité', 'Asimov', 1955, 8),
|
||||
(16, 'De la Terre à la Lune', 'Verne', 1865, 10);
|
||||
```
|
||||
|
||||
- Exécutez la requête en cliquant sur le bouton ▶ ou en appuyant sur F5.
|
||||
- Un message de confirmation devrait apparaître.
|
||||
|
||||

|
||||
|
||||
2. **Vérifier les données insérées** :
|
||||
- Cliquez sur l'onglet "Parcourir les données" pour voir les enregistrements ajoutés.
|
||||
|
||||

|
||||
|
||||
## Activité 3.4 : Exécution de requêtes SQL
|
||||
|
||||
1. **Sélectionner tous les enregistrements** :
|
||||
- Dans l'onglet "Exécuter le SQL", saisissez la requête suivante :
|
||||
|
||||
```sql
|
||||
SELECT id, titre, auteur, ann_publi, note FROM LIVRES;
|
||||
```
|
||||
|
||||
- Exécutez la requête. Vous devriez obtenir tous les enregistrements de la table `LIVRES`.
|
||||
|
||||

|
||||
|
||||
2. **Sélectionner des colonnes spécifiques** :
|
||||
- Pour obtenir uniquement les titres et auteurs des livres, utilisez la requête :
|
||||
|
||||
```sql
|
||||
SELECT titre, auteur FROM LIVRES;
|
||||
```
|
||||
|
||||
3. **Filtrer les enregistrements** :
|
||||
- Pour obtenir les livres écrits par Asimov, utilisez :
|
||||
|
||||
```sql
|
||||
SELECT titre, ann_publi FROM LIVRES WHERE auteur = 'Asimov';
|
||||
```
|
||||
|
||||
4. **Combiner des conditions** :
|
||||
- Pour obtenir les livres d'Asimov publiés après 1953 :
|
||||
|
||||
```sql
|
||||
SELECT titre, ann_publi FROM LIVRES WHERE auteur = 'Asimov' AND ann_publi > 1953;
|
||||
```
|
||||
|
||||
5. **Trier les résultats** :
|
||||
- Pour trier les livres de K.Dick du plus ancien au plus récent :
|
||||
|
||||
```sql
|
||||
SELECT titre FROM LIVRES WHERE auteur = 'K.Dick' ORDER BY ann_publi;
|
||||
```
|
||||
|
||||
|
||||
|
||||
6. Écrivez et testez une requête permettant d'obtenir uniquement les titres des livres écrits par Philip K.Dick.
|
||||
|
||||
7. Saisissez et testez la requête SQL suivante :
|
||||
|
||||
```sql
|
||||
SELECT titre, ann_publi
|
||||
FROM LIVRES
|
||||
WHERE auteur='Asimov' AND ann_publi>1953
|
||||
```
|
||||
|
||||
Vérifiez que vous obtenez bien les livres écrits par Asimov publiés après 1953.
|
||||
|
||||
8. Écrivez une requête permettant d'obtenir les titres des livres publiés après 1945 qui ont une note supérieure ou égale à 9.
|
||||
|
||||
9. Écrivez une requête SQL permettant d'obtenir les livres de K.Dick classés du plus ancien au plus récent.
|
||||
|
||||
10. Créez une nouvelle base de données que vous nommerez par exemple db_livres_auteurs.db, puis créez une table AUTEURS à l'aide de la requête SQL suivante :
|
||||
|
||||
```sql
|
||||
CREATE TABLE AUTEURS
|
||||
(id INT, nom TEXT, prenom TEXT, ann_naissance INT, langue_ecriture TEXT, PRIMARY KEY (id));
|
||||
```
|
||||
|
||||
|
||||
Créez ensuite une deuxième table (LIVRES) :
|
||||
|
||||
```
|
||||
CREATE TABLE LIVRES
|
||||
(id INT, titre TEXT, id_auteur INT, ann_publi INT, note INT, PRIMARY KEY (id), FOREIGN KEY (id_auteur) REFERENCES AUTEURS(id));
|
||||
```
|
||||
|
||||
Comme vous l'avez sans doute remarqué nous avons précisé dans notre requête que l'attribut "id_auteur" jouera le rôle de clé étrangère : liaison entre "id_auteur" de la table LIVRES et "id" de la table AUTEURS (FOREIGN KEY (id_auteur) REFERENCES AUTEURS(id)).
|
||||
|
||||
Ajoutez des données à la table AUTEURS à l'aide de la requête SQL suivante :
|
||||
|
||||
```sql
|
||||
INSERT INTO AUTEURS
|
||||
(id,nom,prenom,ann_naissance,langue_ecriture)
|
||||
VALUES
|
||||
(1,'Orwell','George',1903,'anglais'),
|
||||
(2,'Herbert','Frank',1920,'anglais'),
|
||||
(3,'Asimov','Isaac',1920,'anglais'),
|
||||
(4,'Huxley','Aldous',1894,'anglais'),
|
||||
(5,'Bradbury','Ray',1920,'anglais'),
|
||||
(6,'K.Dick','Philip',1928,'anglais'),
|
||||
(7,'Barjavel','René',1911,'français'),
|
||||
(8,'Boulle','Pierre',1912,'français'),
|
||||
(9,'Van Vogt','Alfred Elton',1912,'anglais'),
|
||||
(10,'Verne','Jules',1828,'français');
|
||||
```
|
||||
|
||||
Ajoutez des données à la table LIVRES à l'aide de la requête SQL suivante :
|
||||
|
||||
```sql
|
||||
INSERT INTO LIVRES
|
||||
(id,titre,id_auteur,ann_publi,note)
|
||||
VALUES
|
||||
(1,'1984',1,1949,10),
|
||||
(2,'Dune',2,1965,8),
|
||||
(3,'Fondation',3,1951,9),
|
||||
(4,'Le meilleur des mondes',4,1931,7),
|
||||
(5,'Fahrenheit 451',5,1953,7),
|
||||
(6,'Ubik',6,1969,9),
|
||||
(7,'Chroniques martiennes',5,1950,8),
|
||||
(8,'La nuit des temps',7,1968,7),
|
||||
(9,'Blade Runner',6,1968,8),
|
||||
(10,'Les Robots',3,1950,9),
|
||||
(11,'La Planète des singes',8,1963,8),
|
||||
(12,'Ravage',7,1943,8),
|
||||
(13,'Le Maître du Haut Château',6,1962,8),
|
||||
(14,'Le monde des Ā',9,1945,7),
|
||||
(15,'La Fin de l’éternité',3,1955,8),
|
||||
(16,'De la Terre à la Lune',10,1865,10);
|
||||
```
|
||||
|
||||
11. Saisissez et testez la requête SQL suivante :
|
||||
|
||||
```sql
|
||||
SELECT titre,nom, prenom
|
||||
FROM LIVRES
|
||||
INNER JOIN AUTEURS ON LIVRES.id_auteur = AUTEURS.id
|
||||
```
|
||||
|
||||
Rappel : attention, si un même nom d'attribut est présent dans les 2 tables (par exemple ici l'attribut id), il est nécessaire d'ajouter le nom de la table devant afin de pouvoir les distinguer (AUTEURS.id et LIVRES.id).
|
||||
|
||||
12. Écrivez une requête SQL permettant d'obtenir les titres des livres publiés après 1945 ainsi que le nom de leurs auteurs.
|
||||
|
||||
13. Nous allons repartir avec une nouvelle base de données. Créez une nouvelle base de données nommée "db_livres.db".
|
||||
|
||||
Créez ensuite une table LIVRES à l'aide de la requête suivante :
|
||||
|
||||
```sql
|
||||
CREATE TABLE LIVRES
|
||||
(id INT, titre TEXT, auteur TEXT, ann_publi INT, note INT, PRIMARY KEY (id));
|
||||
```
|
||||
|
||||
Ajoutez des données à la table LIVRES à l'aide de la requête SQL suivante :
|
||||
|
||||
```sql
|
||||
INSERT INTO LIVRES
|
||||
(id,titre,auteur,ann_publi,note)
|
||||
VALUES
|
||||
(1,'1984','Orwell',1949,10),
|
||||
(2,'Dune','Herbert',1965,8),
|
||||
(3,'Fondation','Asimov',1951,9),
|
||||
(4,'Le meilleur des mondes','Huxley',1931,7),
|
||||
(5,'Fahrenheit 451','Bradbury',1953,7),
|
||||
(6,'Ubik','K.Dick',1969,9),
|
||||
(7,'Chroniques martiennes','Bradbury',1950,8),
|
||||
(8,'La nuit des temps','Barjavel',1968,7),
|
||||
(9,'Blade Runner','K.Dick',1968,8),
|
||||
(10,'Les Robots','Asimov',1950,9),
|
||||
(11,'La Planète des singes','Boulle',1963,8),
|
||||
(12,'Ravage','Barjavel',1943,8),
|
||||
(13,'Le Maître du Haut Château','K.Dick',1962,8),
|
||||
(14,'Le monde des Ā','Van Vogt',1945,7),
|
||||
(15,'La Fin de l’éternité','Asimov',1955,8),
|
||||
(16,'De la Terre à la Lune','Verne',1865,10);
|
||||
```
|
||||
|
||||
14. À l'aide d'une requête SQL, ajoutez à la table LIVRES le livre suivant :
|
||||
- id : 17
|
||||
- titre : "2001 : L'Odyssée de l'espace"
|
||||
- auteur : "Clarke"
|
||||
- année de publication : 1968
|
||||
- note : 7
|
||||
|
||||
|
||||
|
||||
15. Écrivez une requête permettant d'attribuer la note de 10 à tous les livres écrits par Asimov publiés après 1950. Testez cette requête.
|
||||
16. Écrivez une requête permettant de supprimer les livres publiés avant 1945. Testez cette requête.
|
||||
|
||||
## Activité 3.5 : Fonctions d'agrégation
|
||||
|
||||
> **Prérequis** : utiliser la base `db_livres.db` créée à l'activité 3.4 (avec la table LIVRES simple, avant les suppressions de la question 16 — si vous avez supprimé des lignes, réinsérez les données avec le `INSERT INTO` de l'activité 3.4).
|
||||
|
||||
Les fonctions d'agrégation effectuent un calcul sur un ensemble de lignes et renvoient **une seule valeur**.
|
||||
|
||||
### 1. Compter des enregistrements : COUNT
|
||||
|
||||
Exécutez les requêtes suivantes et notez les résultats :
|
||||
|
||||
```sql
|
||||
-- Nombre total de livres
|
||||
SELECT COUNT(*) FROM LIVRES;
|
||||
|
||||
-- Nombre de livres écrits par Asimov
|
||||
SELECT COUNT(*) FROM LIVRES WHERE auteur = 'Asimov';
|
||||
```
|
||||
|
||||
> `COUNT(*)` compte toutes les lignes. La clause `WHERE` s'applique **avant** le comptage.
|
||||
|
||||
### 2. Calculer une moyenne, un min, un max : AVG, MIN, MAX
|
||||
|
||||
```sql
|
||||
-- Note moyenne de tous les livres
|
||||
SELECT AVG(note) FROM LIVRES;
|
||||
|
||||
-- Note la plus basse et la plus haute
|
||||
SELECT MIN(note), MAX(note) FROM LIVRES;
|
||||
|
||||
-- Livre le plus ancien
|
||||
SELECT MIN(ann_publi) FROM LIVRES;
|
||||
```
|
||||
|
||||
> Les alias permettent de nommer le résultat :
|
||||
> ```sql
|
||||
> SELECT AVG(note) AS note_moyenne FROM LIVRES;
|
||||
> ```
|
||||
|
||||
17. Écrivez une requête donnant la note moyenne des livres de Bradbury.
|
||||
|
||||
18. Écrivez une requête donnant l'année de publication du livre le plus récent dans la base.
|
||||
|
||||
### 3. Regrouper les résultats : GROUP BY
|
||||
|
||||
`GROUP BY` divise les lignes en groupes selon les valeurs d'une colonne, et applique la fonction d'agrégation à chaque groupe séparément.
|
||||
|
||||
```sql
|
||||
-- Nombre de livres par auteur
|
||||
SELECT auteur, COUNT(*) AS nb_livres
|
||||
FROM LIVRES
|
||||
GROUP BY auteur;
|
||||
```
|
||||
|
||||
Exécutez cette requête. Vous devriez obtenir une ligne par auteur avec son nombre de livres.
|
||||
|
||||
```sql
|
||||
-- Note moyenne par auteur
|
||||
SELECT auteur, AVG(note) AS note_moyenne
|
||||
FROM LIVRES
|
||||
GROUP BY auteur
|
||||
ORDER BY note_moyenne DESC;
|
||||
```
|
||||
|
||||
19. Écrivez une requête donnant, pour chaque auteur, l'année de son livre le plus ancien.
|
||||
|
||||
### 4. Filtrer les groupes : HAVING
|
||||
|
||||
`WHERE` filtre les lignes **avant** le regroupement. Pour filtrer les groupes **après**, on utilise `HAVING`.
|
||||
|
||||
```sql
|
||||
-- Auteurs ayant écrit au moins 2 livres dans la base
|
||||
SELECT auteur, COUNT(*) AS nb_livres
|
||||
FROM LIVRES
|
||||
GROUP BY auteur
|
||||
HAVING COUNT(*) >= 2;
|
||||
```
|
||||
|
||||
> **À retenir :** `WHERE` porte sur les lignes individuelles, `HAVING` porte sur les groupes.
|
||||
|
||||
```sql
|
||||
-- Auteurs dont la note moyenne dépasse 8
|
||||
SELECT auteur, AVG(note) AS note_moyenne
|
||||
FROM LIVRES
|
||||
GROUP BY auteur
|
||||
HAVING AVG(note) > 8;
|
||||
```
|
||||
|
||||
20. Écrivez une requête listant les auteurs ayant publié des livres dans **deux décennies différentes** au minimum.
|
||||
*(Indice : `MIN(ann_publi)` et `MAX(ann_publi)` dans le même GROUP BY, puis filtrer avec HAVING sur la différence)*
|
||||
|
||||
21. Écrivez une requête donnant, parmi les auteurs ayant au moins 2 livres, celui dont la note moyenne est la plus élevée. Triez de façon appropriée et limitez à 1 résultat.
|
||||
|
||||
--------
|
||||
|
||||
Source :
|
||||
|
||||
- [Pixees, site de David Roche](https://informatique-lycee.forge.apps.education.fr/terminale_nsi/cours-terminale/c3a/)
|
||||
|
||||
---
|
||||
|
||||
Auteur : Florian Mathieu
|
||||
|
||||
Licence CC BY NC
|
||||
|
||||
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="Licence Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-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-nc-sa/4.0/">Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International</a>.
|
||||
|
||||
Reference in New Issue
Block a user