Exercices SQL corrigés : UNION, INTERSECT, EXCEPT

Exercices SQL corrigés : UNION, INTERSECT, EXCEPT

Mis à jour le

UNION réunit deux résultats (sans doublon), INTERSECT garde ce qu’ils ont en commun, EXCEPT retire le second du premier. Ces 11 exercices vont du niveau 4 au niveau 4 ; ils utilisent la syntaxe de SQLite, le moteur SQL de SpeedQL.

Conseil : Les deux requêtes doivent renvoyer le même nombre de colonnes.

Relire la fiche « UNION, INTERSECT, EXCEPT » de l’aide-mémoire

Exercice 1 · niveau 4

Affiche la liste, sans doublon, de tous les membres des deux clubs (tables chess et music). Utilise UNION.

Table chess (4 lignes)
member
Alice
Bob
Claire
David
Table music (4 lignes)
member
Claire
David
Emma
Farid
Voir l’indice

Notions à utiliser : UNION, INTERSECT, EXCEPT.

Structure de la requête :

SELECT 
FROM 
UNION SELECT 
FROM 
Voir la correction
SELECT member
FROM chess
UNION SELECT member
FROM music;

Résultat attendu (6 lignes) :

member
Alice
Bob
Claire
David
Emma
Farid

Exercice 2 · niveau 4

Affiche les membres inscrits aux deux clubs à la fois. Utilise INTERSECT.

Table chess (4 lignes)
member
Alice
Bob
Claire
David
Table music (4 lignes)
member
Claire
David
Emma
Farid
Voir l’indice

Notions à utiliser : UNION, INTERSECT, EXCEPT.

Structure de la requête :

SELECT 
FROM 
INTERSECT SELECT 
FROM 
Voir la correction
SELECT member
FROM chess
INTERSECT SELECT member
FROM music;

Résultat attendu (2 lignes) :

member
Claire
David

Exercice 3 · niveau 4

Affiche les membres du club chess qui ne sont pas dans le club music. Utilise EXCEPT.

Table chess (4 lignes)
member
Alice
Bob
Claire
David
Table music (4 lignes)
member
Claire
David
Emma
Farid
Voir l’indice

Notions à utiliser : UNION, INTERSECT, EXCEPT.

Structure de la requête :

SELECT 
FROM 
EXCEPT SELECT 
FROM 
Voir la correction
SELECT member
FROM chess
EXCEPT SELECT member
FROM music;

Résultat attendu (2 lignes) :

member
Alice
Bob

Exercice 4 · niveau 4

Affiche les genres dont tous les films ont une note d'au moins 7 : prends les genres qui ont un film noté au moins 7, sauf ceux qui ont un film noté moins de 7. Utilise EXCEPT.

Table movies (10 lignes)
idtitlegenreyeardurationratingdirector_id
1Night TrainThriller20151187.81
2Blue HarborDrama20181027.12
3Paper Moon CityComedy2012956.45
4Silent PeakDrama20201318.23
5Last SignalSci-Fi20191427.51
6Summer KeysComedy2016885.94
7Iron GardenSci-Fi202112583
8Dust and GoldWestern20141106.82
9The Quiet HourDrama2022977.45
10Deep CurrentThriller20171056.9NULL
Voir l’indice

Notions à utiliser : WHERE (filtres), UNION, INTERSECT, EXCEPT.

Structure de la requête :

SELECT 
FROM 
WHERE  >= 
EXCEPT SELECT 
FROM 
WHERE  < 
Voir la correction
SELECT genre
FROM movies
WHERE rating >= 7
EXCEPT SELECT genre
FROM movies
WHERE rating < 7;

Résultat attendu (2 lignes) :

genre
Drama
Sci-Fi

Exercice 5 · niveau 4

Affiche le titre des livres empruntés à la fois par un membre de Paris et par un membre de Lille. Utilise INTERSECT.

Table books (10 lignes)
idtitleauthor_idgenrepagesyear
1Cold River1Novel3202011
2Salt Roads2Travel2102016
3The Glass Hive3Sci-Fi4122019
4Winter Ledger1Crime2882014
5Desert Letters2Novel3562020
6Small Engines4Sci-Fi1982022
7Harbor Lights5Novel4452008
8Night Garden3Crime3012017
9Paper Birds5Poetry962012
10Open Maps4Travel2402021
Table loans (12 lignes)
idbook_idmember_idloan_datereturn_date
1112025-01-052025-01-19
2322025-01-102025-02-02
3512025-02-012025-02-10
4732025-02-03NULL
5342025-02-152025-03-01
6222025-03-022025-03-30
7852025-03-05NULL
8132025-03-102025-03-18
9612025-03-202025-04-15
10352025-04-01NULL
11942025-04-052025-04-12
121022025-04-082025-04-20
Table members (6 lignes)
idnamecityjoined
1LenaLyon2022-01-15
2MarcParis2021-06-03
3NadiaLyon2023-03-20
4OscarLille2020-11-11
5PaulaParis2024-02-01
6QuentinNantes2023-09-09
Voir l’indice

Notions à utiliser : WHERE (filtres), JOIN, UNION, INTERSECT, EXCEPT.

Structure de la requête :

SELECT 
FROM  
JOIN   ON  = 
JOIN   ON  = 
WHERE  = 
INTERSECT SELECT 
FROM  
JOIN   ON  = 
JOIN   ON  = 
WHERE  = 
Voir la correction
SELECT b.title
FROM books b
JOIN loans l ON l.book_id = b.id
JOIN members m ON m.id = l.member_id
WHERE m.city = 'Paris'
INTERSECT SELECT b.title
FROM books b
JOIN loans l ON l.book_id = b.id
JOIN members m ON m.id = l.member_id
WHERE m.city = 'Lille';

Résultat attendu (1 ligne) :

title
The Glass Hive

Exercice 6 · niveau 4

Affiche, sans doublon, le nom des équipes qui ont gagné au moins un match, à domicile ou à l'extérieur. Utilise UNION.

Table teams (5 lignes)
idnamecityfounded
1Red FoxesLyon1950
2Blue OwlsParis1962
3Green BullsLille1971
4Gold HawksNantes1988
5Grey WolvesParis1990
Table matches (10 lignes)
idplayed_onhome_idaway_idhome_goalsaway_goals
12025-08-021221
22025-08-033400
32025-08-095113
42025-08-102322
52025-08-164531
62025-08-171310
72025-08-232401
82025-08-243523
92025-08-304111
102025-08-315202
Voir l’indice

Notions à utiliser : WHERE (filtres), JOIN, UNION, INTERSECT, EXCEPT.

Structure de la requête :

SELECT 
FROM  
JOIN   ON  = 
WHERE  > 
UNION SELECT 
FROM  
JOIN   ON  = 
WHERE  > 
Voir la correction
SELECT t.name
FROM teams t
JOIN matches m ON m.home_id = t.id
WHERE m.home_goals > m.away_goals
UNION SELECT t.name
FROM teams t
JOIN matches m ON m.away_id = t.id
WHERE m.away_goals > m.home_goals;

Résultat attendu (4 lignes) :

name
Blue Owls
Gold Hawks
Grey Wolves
Red Foxes

Exercice 7 · niveau 4

Affiche les villes d'arrivée desservies à la fois par SkyJet et par AirNova. Utilise INTERSECT.

Table flights (12 lignes)
idairlineorigindestdepartsduration_minpriceseats_soldcapacity
1SkyJetCDGMAD2025-06-01 08:1012589150180
2AirNovaCDGLIS2025-06-01 11:40155120160170
3BlueWingLYSFCO2025-06-02 07:309575110150
4SkyJetMADCDG2025-06-02 18:2012095170180
5AirNovaBERCDG2025-06-03 09:05110105140160
6BlueWingNCEBER2025-06-03 13:5013014090150
7SkyJetCDGFCO2025-06-04 06:4513599175180
8AirNovaLISMAD2025-06-04 16:15756560120
9BlueWingFCOLYS2025-06-05 20:3010082130150
10SkyJetCDGBER2025-06-05 10:00105110120180
11AirNovaMADLIS2025-06-06 12:25807095120
12BlueWingLYSMAD2025-06-06 15:4011579100150
Table airports (7 lignes)
codecitycountry
CDGParisFrance
LYSLyonFrance
MADMadridSpain
LISLisbonPortugal
FCORomeItaly
BERBerlinGermany
NCENiceFrance
Voir l’indice

Notions à utiliser : WHERE (filtres), JOIN, UNION, INTERSECT, EXCEPT.

Structure de la requête :

SELECT 
FROM  
JOIN   ON  = 
WHERE  = 
INTERSECT SELECT 
FROM  
JOIN   ON  = 
WHERE  = 
Voir la correction
SELECT a.city
FROM flights f
JOIN airports a ON a.code = f.dest
WHERE f.airline = 'SkyJet'
INTERSECT SELECT a.city
FROM flights f
JOIN airports a ON a.code = f.dest
WHERE f.airline = 'AirNova';

Résultat attendu (2 lignes) :

city
Madrid
Paris

Exercice 8 · niveau 4

Affiche les jours où il a plu à la fois à Paris et à Lyon. Utilise INTERSECT.

Table readings (15 lignes)
idcitydaytemp_maxtemp_minrain_mm
1Paris2025-07-0124150
2Paris2025-07-0227170
3Paris2025-07-0322164.5
4Paris2025-07-04191412
5Paris2025-07-0523130
6Lyon2025-07-0126160
7Lyon2025-07-0229180
8Lyon2025-07-0331190
9Lyon2025-07-0424178.5
10Lyon2025-07-0522153
11Marseille2025-07-0130210
12Marseille2025-07-0232220
13Marseille2025-07-0333230
14Marseille2025-07-0429210
15Marseille2025-07-0528200
Voir l’indice

Notions à utiliser : WHERE (filtres), UNION, INTERSECT, EXCEPT.

Structure de la requête :

SELECT 
FROM 
WHERE  =  AND  > 
INTERSECT SELECT 
FROM 
WHERE  =  AND  > 
Voir la correction
SELECT day
FROM readings
WHERE city = 'Paris' AND rain_mm > 0
INTERSECT SELECT day
FROM readings
WHERE city = 'Lyon' AND rain_mm > 0;

Résultat attendu (1 ligne) :

day
2025-07-04

Exercice 9 · niveau 4

Avec EXCEPT, affiche les pays des clients, sauf ceux des clients qui ont séjourné dans un hôtel de Paris.

Table guests (6 lignes)
idnamecountry
1Ana SilvaPortugal
2Ben FordUSA
3Chen LiChina
4Dana WeissGermany
5Emma RoyFrance
6Farid NasserMorocco
Table bookings (11 lignes)
idroom_idguest_idcheck_incheck_out
1212025-07-012025-07-04
2522025-07-022025-07-05
3832025-07-032025-07-06
4342025-07-052025-07-12
5652025-07-062025-07-08
6122025-07-082025-07-10
7932025-07-102025-07-11
8752025-07-112025-07-15
9412025-07-142025-07-16
10642025-07-152025-07-19
11652025-07-162025-07-18
Table rooms (10 lignes)
idhotel_idtypeprice
11single70
21double95
32double130
42suite210
53single110
63double150
74double65
85double260
95suite480
105single190
Table hotels (5 lignes)
idnamecitystars
1Seaside InnNice3
2Alpine LodgeAnnecy4
3City LoftParis4
4Old MillBordeaux2
5Grand PalaceParis5
Voir l’indice

Notions à utiliser : WHERE (filtres), JOIN, UNION, INTERSECT, EXCEPT.

Structure de la requête :

SELECT 
FROM 
EXCEPT SELECT 
FROM  
JOIN   ON  = 
JOIN   ON  = 
JOIN   ON  = 
WHERE  = 
Voir la correction
SELECT country
FROM guests
EXCEPT SELECT g.country
FROM guests g
JOIN bookings b ON b.guest_id = g.id
JOIN rooms r ON r.id = b.room_id
JOIN hotels h ON h.id = r.hotel_id
WHERE h.city = 'Paris';

Résultat attendu (2 lignes) :

country
Morocco
Portugal

Exercice 10 · niveau 4

Avec INTERSECT, affiche le nom des clients qui ont commandé à la fois un produit Office et un produit Kitchen.

Table customers (6 lignes)
idnamecitysignup
1AlbaParis2024-01-10
2BorisLyon2024-02-15
3CarlaParis2024-03-01
4DenisNantes2024-05-20
5EvaLyon2024-06-30
6FabioLille2024-08-08
Table orders (8 lignes)
idcustomer_idorder_datestatus
112025-01-05shipped
222025-01-12shipped
312025-02-03paid
432025-02-10cancelled
542025-02-20shipped
652025-03-02shipped
722025-03-15paid
832025-03-28shipped
Table order_items (14 lignes)
order_idproduct_idqty
111
122
241
335
321
451
562
511
624
633
741
761
852
821
Table products (7 lignes)
idnamecategoryprice
1Desk LampHome35
2Coffee MugKitchen12
3NotebookOffice6
4Office ChairOffice149
5KettleKitchen45
6CushionHome22
7StaplerOffice9
Voir l’indice

Notions à utiliser : WHERE (filtres), JOIN, UNION, INTERSECT, EXCEPT.

Structure de la requête :

SELECT 
FROM  
JOIN   ON  = 
JOIN   ON  = 
JOIN   ON  = 
WHERE  = 
INTERSECT SELECT 
FROM  
JOIN   ON  = 
JOIN   ON  = 
JOIN   ON  = 
WHERE  = 
Voir la correction
SELECT c.name
FROM customers c
JOIN orders o ON o.customer_id = c.id
JOIN order_items oi ON oi.order_id = o.id
JOIN products p ON p.id = oi.product_id
WHERE p.category = 'Office'
INTERSECT SELECT c.name
FROM customers c
JOIN orders o ON o.customer_id = c.id
JOIN order_items oi ON oi.order_id = o.id
JOIN products p ON p.id = oi.product_id
WHERE p.category = 'Kitchen';

Résultat attendu (2 lignes) :

name
Alba
Eva

Exercice 11 · niveau 4

Avec UNION, affiche sans doublon les titulaires qui ont reçu un salaire (label 'salary') et ceux qui ont un compte épargne (kind 'savings').

Table accounts (6 lignes)
idownercityopenedkind
1AliceParis2021-03-01current
2AliceParis2022-06-15savings
3BrunoLyon2020-09-10current
4ChloeLyon2023-01-20current
5DavidNice2019-11-05savings
6EmmaNice2024-04-01current
Table transactions (14 lignes)
idaccount_idmade_onamountlabel
112025-01-022500salary
212025-01-05-60groceries
312025-01-12-800rent
422025-01-15500transfer
532025-01-031900salary
632025-01-20-120groceries
732025-02-01-950rent
842025-01-252100salary
942025-02-03-45restaurant
1012025-02-022600salary
1112025-02-06-75groceries
1252025-02-1030interest
1322025-02-15500transfer
1442025-02-18-600rent
Voir l’indice

Notions à utiliser : WHERE (filtres), JOIN, UNION, INTERSECT, EXCEPT.

Structure de la requête :

SELECT 
FROM  
JOIN   ON  = 
WHERE  = 
UNION SELECT 
FROM 
WHERE  = 
Voir la correction
SELECT a.owner
FROM accounts a
JOIN transactions t ON t.account_id = a.id
WHERE t.label = 'salary'
UNION SELECT owner
FROM accounts
WHERE kind = 'savings';

Résultat attendu (4 lignes) :

owner
Alice
Bruno
Chloe
David

S’entraîner avec correction automatique

Dans SpeedQL, tu écris ta requête et elle est vérifiée tout de suite, sur ces tables puis sur un jeu de données caché.

S’entraîner sur les 13 questions « UNION, INTERSECT, EXCEPT »