10 SQL
F pour passer en plein écran ou O pour afficher la vue d'ensemble.
Versions sans animation, plein écran, imprimable.
Objectifs
Comment manipuler les données ?
Exercices
PostgreSQL
- Installer PostgreSQL.
- macOS :
brew install postgresql- Username : votre nom d'utilisateur (
whoamipour le retrouver) - Password : aucun
- Port : 5432
- Database :
postgres - pour démarrer PostgreSQL :
brew services start postgresql - pour arrêter PostgreSQL :
brew services stop postgresql
- Username : votre nom d'utilisateur (
- Windows :
choco install postgresql- Username :
postgres - Password : indiqué lors de l'installation
- Port : 5432
- Database :
postgres
- Username :
- macOS :
- Installer DBeaver.
- macOS :
brew install --cask dbeaver-community - Windows :
choco install dbeaver
- macOS :
- Ouvrir DBeaver et se connecter à la base de données PostgreSQL.
- Cliquer sur
Database>New Database Connection. - Sélectionner
PostgreSQL. - Remplir les champs selon les informations d'installation.
- Cliquer sur
Test Connectionpour vérifier que tout fonctionne. - Cliquer sur
Finish.
- Cliquer sur
Personne
- Ouvrir un nouveau SQL Editor.
- Cliquer sur
SQL Editor>Open SQL Editor.
- Cliquer sur
- Créer une nouvelle table
personavec les colonnes suivantes :id:SERIAL PRIMARY KEY(clé primaire entier auto-incrémentée)name:VARCHAR(50)(chaîne de caractères de 50 caractères maximum)email:VARCHAR(100)age:SMALLINT(entier signé sur 2 octets)- Exécuter la commande suivante :
CREATE TABLE person (
id SERIAL PRIMARY KEY,
name VARCHAR(50) NOT NULL,
email VARCHAR(100),
age SMALLINT NOT NULL
);- Cliquer sur (Execute SQL query) pour exécuter la commande.
- Cliquer une seconde fois devrait indiquer une erreur car la table existe déjà.
- Voir la table créée dans le volet "Database navigator" à gauche : nom de la connexion >
Database> nom de la database >Schemas>public>Tables>person.F5pour rafraîchir si la table n'apparaît pas.
- Insérer des données dans la table
person.-
INSERT INTO person (name, email, age)
VALUES
('Alice', 'alice@example.com', 28),
('Bob', 'bob@example.com', 20),
('Charlie', NULL, 25),
('Dave', NULL, 30); - Voir les données dans l'onglet "person" > "Data".
F5pour rafraîchir si les données n'apparaissent pas.
-
- Sélectionner toutes les données de la table
person.Solution
SELECT * FROM person; - Sélectionner uniquement les noms et les âges des personnes.
Solution
SELECT name, age FROM person; - Sélectionner dans l'ordre décroissant des âges.
Solution
SELECT * FROM person
ORDER BY age DESC; - Sélectionner uniquement les personnes de plus de 25 ans.
Solution
SELECT * FROM person
WHERE age > 25; - Sélectionner uniquement les noms des personnes de plus de 25 ans.
Solution
SELECT name FROM person
WHERE age > 25; - Calculer la moyenne d'âge des personnes.
Solution
SELECT AVG(age) FROM person;
Éducation
- Voici des données sur l'éducation en Suisse : https://opendata.swiss/fr/dataset/bildung
- Télécharger le fichier au format CSV.
- Ouvrir le fichier pour observer les données.
geo_name: nom du lieuvariable: degré d'étudesschu_t_20: élèves totaux en 2020/21obl_t_20: total obligatoire en 2020/21obl_p12_20: 1P-2P en 2020/21obl_p38_20: 3P-8P en 2020/21obl_sec1_20: secondaire 1 (9S-11S) en 2020/21
sec_t_20: total secondaire 2 en 2020/21sec_tran_20: formation transitoire sec1-sec2 en 2020/21sec_mat_20: maturités (RRM, MS, MP2) en 2020/21sec_pro_20: formation professionnelle initiale en 2020/21sec_gen_20: autres écoles de formation générale en 2020/21sec_comp_20: formation complémentaires sec2 en 2020/21
- La description des données se trouve dans le fichier ODS.
- Créer une nouvelle table
educationavec les colonnes suivantes :id:SERIAL PRIMARY KEYgeo_nr:VARCHAR(4)geo_name:VARCHAR(22)class_hab:VARCHAR(5)geom_period:DATEvariable:VARCHAR(11)source:CHAR(3)(chaîne de 3 caractères exactement)value_period:CHAR(7)unit_value:CHAR(3)value:INTEGER(entier signé sur 4 octets)status:CHAR(1)- Exécuter la commande suivante :
CREATE TABLE education (
id SERIAL PRIMARY KEY,
geo_nr VARCHAR(4) NOT NULL,
geo_name VARCHAR(22) NOT NULL,
class_hab VARCHAR(5) NOT NULL,
geom_period DATE NOT NULL,
variable VARCHAR(11) NOT NULL,
source CHAR(3) NOT NULL,
value_period CHAR(7) NOT NULL,
unit_value CHAR(3) NOT NULL,
value INTEGER NOT NULL,
status CHAR(1) NOT NULL
);
- Importer les données du fichier CSV dans la table
education.- Clic droit sur la table
education(dans la Database Navigator) >Import Data. - Sélectionner le fichier CSV.
- Vérifier que les colonnes soient correctement associées.
- Cliquer sur
Proceed. - Vérifier les données dans la table
education.
- Clic droit sur la table
- Sélectionner toutes les villes disponibles.
Solution
SELECT DISTINCT geo_name FROM education; - Sélectionner toutes les données concernant les élèves de Lausanne.
Solution
SELECT * FROM education
WHERE geo_name = 'Lausanne'; - Sélectionner le nombre d'élèves avec leur lieu au secondaire 1 dans toutes les villes.
Solution
SELECT geo_name, value FROM education
WHERE variable = 'obl_sec1_20';- Dans l'ordre décroissant des élèves.
Solution
SELECT geo_name, value FROM education
WHERE variable = 'obl_sec1_20'
ORDER BY value DESC; - Ne prendre que les 5 premières villes.
Solution
SELECT geo_name, value FROM education
WHERE variable = 'obl_sec1_20'
ORDER BY value DESC LIMIT 5; - Ne prendre que les 5 premières villes après les 3 premières.
Solution
SELECT geo_name, value FROM education
WHERE variable = 'obl_sec1_20'
ORDER BY value DESC LIMIT 5 OFFSET 3; - Exclure les données de la Suisse.
Solution
SELECT geo_name, value FROM education
WHERE variable = 'obl_sec1_20' AND geo_name <> 'Schweiz / Suisse';- Calculer la moyenne d'élèves au secondaire 1
Solution
SELECT AVG(value) FROM education
WHERE variable = 'obl_sec1_20' AND geo_name <> 'Schweiz / Suisse'; - Calculer le total d'élèves au secondaire 1
Solution
SELECT SUM(value) FROM education
WHERE variable = 'obl_sec1_20' AND geo_name <> 'Schweiz / Suisse';
- Calculer la moyenne d'élèves au secondaire 1
- Dans l'ordre décroissant des élèves.
- Lister dans l'ordre croissant le nombre d'élèves par ville pour les maturités en excluant les données de la Suisse ainsi que les villes qui n'ont pas d'élèves.
Solution
SELECT geo_name, value FROM education
WHERE variable = 'sec_mat_20'
AND geo_name <> 'Schweiz / Suisse'
AND value > 0
ORDER BY value ASC;
Avis de films
Reprendre ta table person et l'étendre pour gérer des avis de films.
- Créer une nouvelle table
movieavec les colonnes suivantes :id:SERIAL PRIMARY KEYtitle:VARCHAR(100)year:SMALLINT-
Solution
CREATE TABLE movie (
id SERIAL PRIMARY KEY,
title VARCHAR(100) NOT NULL,
year SMALLINT NOT NULL
);
- Insérer des données dans la table
movie.-
INSERT INTO movie (title, year)
VALUES
('Memento', 2000),
('The Prestige', 2006),
('The Dark Knight', 2008),
('Inception', 2010),
('Interstellar', 2014),
('Dunkirk', 2017),
('Tenet', 2020),
('Oppenheimer', 2023);
-
- Créer une nouvelle table
reviewavec les colonnes suivantes :id:SERIAL PRIMARY KEYrating:SMALLINT(note de 1 à 6)comment:TEXT(chaîne de caractères sans limite de taille)person_id:INTEGER(clé étrangère vers la tableperson)movie_id:INTEGER(clé étrangère vers la tablemovie)-
CREATE TABLE review (
id SERIAL PRIMARY KEY,
rating SMALLINT NOT NULL,
comment TEXT,
person_id INTEGER NOT NULL,
movie_id INTEGER NOT NULL,
FOREIGN KEY (person_id) REFERENCES person (id),
FOREIGN KEY (movie_id) REFERENCES movie (id)
);
- Insérer les données dans la table
reviewavec les avis suivants :- Alice a noté
Memento5/6. - Alice a noté
Dinkirk3/6 avec le commentairePas mal. - Bob a noté
Memento1/6 avec le commentaireJe n'ai rien compris(il faudra échapper l'apostrophe). - Dave a noté
Tenet4/6. - Charlie a noté
Memento6/6 avec le commentaireChef-d'œuvre. - Bob a noté
Dinkirk2/6 avec le commentaireBof. - Charlie a noté
Oppenheimer4/6 avec le commentaireSympa. -
Solution
INSERT INTO review (rating, comment, person_id, movie_id)
VALUES
(5, NULL, 1, 1),
(3, 'Pas mal', 1, 6),
(1, 'Je n''ai rien compris', 2, 1),
(4, NULL, 4, 7),
(6, 'Chef-d''œuvre', 3, 1),
(2, 'Bof', 2, 6),
(4, 'Sympa', 3, 8);
- Alice a noté
- Sélectionner les avis de tout le monde sur tous les films.
Solution
SELECT * FROM review
JOIN movie ON review.movie_id = movie.id
JOIN person ON review.person_id = person.id;- Ne garder que les titres, les notes et les commentaires.
Solution
SELECT title, rating, comment FROM review
JOIN movie ON review.movie_id = movie.id
JOIN person ON review.person_id = person.id;- Ne garder que les avis de Bob.
Solution
SELECT title, rating, comment FROM review
JOIN movie ON review.movie_id = movie.id
JOIN person ON review.person_id = person.id
WHERE person.name = 'Bob';
- Ne garder que les avis de Bob.
- Ne garder que les avis sur
Mementoavec le nom de la personne au lieu du titre du film.Solution
SELECT name, rating, comment FROM review
JOIN movie ON review.movie_id = movie.id
JOIN person ON review.person_id = person.id
WHERE movie.title = 'Memento';- Ne garder que les avis de plus de 3/6 sur
Memento.Solution
SELECT name, rating, comment FROM review
JOIN movie ON review.movie_id = movie.id
JOIN person ON review.person_id = person.id
WHERE movie.title = 'Memento' AND rating > 3;
- Ne garder que les avis de plus de 3/6 sur
- Ne garder que les titres, les notes et les commentaires.
- Calculer la moyenne des notes de
Memento.Solution
SELECT AVG(rating) FROM review
JOIN movie ON review.movie_id = movie.id
WHERE movie.title = 'Memento';
Bonus

Source : https://xkcd.com/1409/

Source : https://xkcd.com/327/