60 exercices · sandbox postgresql

SQL — Du SELECT à l'Analyse avancée

Chaque exercice s'accompagne d'un éditeur SQL avec correction par IA. Progression de débutant à expert en 60 exercices.

~10 min/ex
SELECT, WHERE, ORDER
~15 min/ex
GROUP BY, JOIN, CTE
~15-20 min/ex
Window Functions
~15-20 min/ex
DDL, DML, Vues
~20-25 min/ex
Performance, Index
~20-30 min/ex
Analytics avancé
~20-25 min/ex
Data Engineering
1
Votre premier SELECT
Affiche toutes les colonnes et toutes les lignes de la table etudiants (utilise l'étoile *).
~10 minSELECT
2
Colonnes spécifiques
Affiche uniquement les colonnes nom et note de la table etudiants.
~10 minSELECT
3
Filtrer avec WHERE
Affiche toutes les colonnes des etudiants dont la note est strictement supérieure à 12 (colonne note).
~10 minWHERE
4
WHERE avec texte
Affiche tous les etudiants dont la ville est 'Paris' (colonne ville — texte entre apostrophes).
~10 minWHERE
5
ORDER BY
Affiche tous les etudiants triés du meilleur au moins bon selon leur note (tri décroissant).
~10 minORDER BY
6
LIMIT
Affiche les 5 etudiants ayant les meilleures notes : trie par note décroissante et limite le résultat à 5 lignes.
~10 minLIMIT
7
COUNT
Compte le nombre total d'etudiants. Nomme la colonne du résultat total.
~10 minAgrégation
8
SUM et AVG
Calcule la somme et la moyenne des notes des etudiants. Nomme les colonnes somme et moyenne.
~10 minAgrégation
9
MIN et MAX
Affiche la note la plus basse et la plus haute des etudiants. Nomme les colonnes min_note et max_note.
~10 minAgrégation
10
GROUP BY
Compte le nombre d'etudiants par ville. Affiche la ville et le compte (nommé nb), en groupant par ville.
~10 minGROUP BY
11
GROUP BY + AVG
Calcule la note moyenne par ville. Affiche la ville et la moyenne (nommée moyenne), en groupant par ville.
~15 minGROUP BY
12
HAVING
Affiche les villes ayant strictement plus de 2 etudiants. Affiche la ville et le compte (nommé nb) ; le filtre s'applique après le regroupement.
~15 minHAVING
13
LIKE
Affiche les etudiants dont le nom commence par la lettre A (LIKE 'A%').
~15 minLIKE
14
IN
Affiche les etudiants dont la ville est Paris, Lyon ou Bordeaux (opérateur IN).
~15 minIN
15
BETWEEN
Affiche les etudiants dont la note est comprise entre 10 et 15 inclus (bornes comprises).
~15 minBETWEEN
16
IS NULL
Affiche les etudiants sans email renseigné (email IS NULL).
~15 minNULL
17
COALESCE
Affiche le nom et l'email de chaque etudiant, en remplaçant les emails NULL par le texte 'non renseigné'. Nomme la colonne du résultat email (COALESCE).
~15 minNULL
18
DISTINCT
Affiche la liste des villes sans doublon, triées par ordre alphabétique.
~15 minDISTINCT
19
AS - alias
Affichez les colonnes de la table etudiants en les renommant avec des alias (AS) : nom -> "Nom complet", note -> "Score", ville -> "Localisation". Utilise des guillemets doubles pour les alias contenant un espace ou une majuscule.
~15 minAlias
20
INSERT
Insère un nouvel etudiant avec les colonnes nom, note, ville : nom 'Emma', note 16, ville 'Nantes'.
~15 minCRUD
21
UPDATE
Mets la note de l'etudiant nommé 'Alice' à 18.
~20 minCRUD
22
DELETE
Supprime les etudiants dont la note est strictement inférieure à 5.
~20 minCRUD
23
CREATE TABLE
Crée une table salles avec 4 colonnes : id (clé primaire auto-incrémentée, SERIAL), nom (texte obligatoire, VARCHAR NOT NULL), batiment (texte), capacite (entier INT).
~20 minDDL
24
ALTER TABLE
Ajoute une colonne telephone de type VARCHAR(20) à la table etudiants (ALTER TABLE ... ADD COLUMN).
~20 minDDL
25
JOIN INNER
Affiche le nom de chaque étudiant avec le nom de son cours. Joins etudiants → inscriptions (via etudiant_id) → cours (via cours_id) en INNER JOIN. Donne un alias court à chaque table (les lettres sont au choix) puis affiche deux colonnes : le nom de l'étudiant et le nom du cours.
~20 minJOIN
26
LEFT JOIN
Affiche tous les étudiants et le nom de leurs cours, y compris ceux sans inscription (LEFT JOIN au lieu de INNER JOIN). Mêmes tables et alias au choix que l'exercice précédent ; les colonnes du cours valent NULL si l'étudiant n'a aucune inscription.
~20 minJOIN
27
Sous-requête
Affiche le nom et la note des etudiants dont la note dépasse la moyenne générale (calcule cette moyenne avec une sous-requête). Colonnes : nom, note.
~20 minSous-requêtes
28
Sous-requête IN
Affiche le nom des etudiants inscrits au cours 'Python'. Passe par la table inscriptions (etudiant_id, cours_id) et retrouve l'id du cours 'Python' dans la table cours, via une sous-requête avec IN.
~20 minSous-requêtes
29
CASE WHEN
Affiche nom, note et une colonne mention calculée avec CASE selon la note : ≥16 → 'Excellent', ≥12 → 'Bien', ≥10 → 'Moyen', sinon → 'Insuffisant'. Nomme la colonne mention.
~20 minCASE
30
CTE (WITH)
Avec une CTE (WITH), classe les etudiants par note décroissante grâce à une fonction de rang (colonne nommée rang), puis n'affiche que les 3 premiers. Colonnes : nom, note, rang.
~20 minCTE
31
Fonctions fenêtre - ROW_NUMBER
Numérote les etudiants à l'intérieur de chaque ville, du meilleur au moins bon, avec une fonction fenêtre. Nomme cette colonne rang_ville. Colonnes : nom, ville, note, rang_ville.
~20 minWindow Functions
32
LAG et LEAD
Sur la table ventes (colonnes date_vente, montant), affiche pour chaque vente le montant de la vente précédente et de la suivante, triées par date_vente. Nomme les colonnes vente_precedente et vente_suivante.
~20 minWindow Functions
33
SUM cumulatif
Sur la table ventes, calcule le chiffre d'affaires cumulé au fil des dates (somme progressive du montant avec une fonction fenêtre). Colonnes : date_vente, montant, ca_cumule.
~20 minWindow Functions
34
PERCENTILE
Calcule la médiane des notes des etudiants avec la fonction PERCENTILE_CONT. Nomme la colonne mediane.
~20 minStatistiques SQL
35
Date functions
Affiche le nom et la date d'inscription des etudiants inscrits il y a moins de 30 jours : date_inscription >= CURRENT_DATE - INTERVAL '30 days'. Colonnes : nom, date_inscription.
~20 minDates
36
EXTRACT
Compte le nombre d'inscriptions par mois et année, en extrayant l'année et le mois de date_inscription. Colonnes : annee, mois, nb. Groupe et trie par annee puis mois.
~25 minDates
37
String functions
Pour les etudiants ayant un email, affiche leur nom en majuscules (colonne nom_maj) et le domaine de leur email — la partie située après le @ (colonne domaine).
~25 minStrings
38
CONCAT
Crée une colonne nom_complet en combinant le prénom et le nom, séparés d'un espace. Affiche aussi la ville. Colonnes : nom_complet, ville.
~25 minStrings
39
INDEX
Crée un index nommé idx_ville sur la colonne ville de la table etudiants. Un index accélère les requêtes qui filtrent sur cette colonne (la leçon montre comment le vérifier avec EXPLAIN).
~25 minOptimisation
40
VIEW
Crée une vue nommée top_etudiants contenant nom, note, ville des 10 meilleurs etudiants (les 10 meilleures notes). Une fois créée, on peut l'interroger comme une table.
~25 minVues
41
Transactions
Dans une transaction (BEGIN ... COMMIT), insère un étudiant ('Pierre', note 14) puis une inscription qui le relie au cours 1, de façon atomique. Récupère l'id du nouvel étudiant via la séquence de la table (currval).
~25 minTransactions
42
UNION
Combine avec UNION les etudiants de Paris et ceux de Lyon. Affiche nom, prenom, ville, triés par nom.
~25 minUNION
43
INTERSECT et EXCEPT
Avec INTERSECT et EXCEPT, compare deux ensembles d'etudiants : ceux inscrits a la fois en Python (cours 1) ET en SQL (cours 2), puis ceux inscrits en Python mais PAS en SQL.
~25 minEnsembles
44
Corrélation SQL
Affiche les etudiants dont la note dépasse la moyenne des notes de LEUR propre ville (sous-requête corrélée). Colonnes : nom, prenom, note, ville. Trie par ville puis note décroissante.
~25 minStatistiques SQL
45
JSON en SQL
Pour chaque etudiant, construis un objet JSON regroupant son nom, sa ville et sa note, dans une colonne nommée profil_json. Affiche aussi nom, ville, note. Trie par nom et limite à 5 lignes.
~25 minJSON
46
ARRAY functions
Affiche le nom des etudiants dont le tableau competences contient 'Python' (utilise un opérateur de recherche dans un tableau).
~30 minArrays
47
Requête récursive
Sur la table employes (colonnes id, nom, manager_id), génère la hiérarchie avec WITH RECURSIVE : démarre par les employés sans manager (manager_id IS NULL, niveau 0), puis descend d'un niveau à chaque étape. Colonnes : id, nom, manager_id, niveau.
~30 minRécursivité
48
Performance - EXPLAIN
Écris la requête qui compte le nombre de cours par étudiant (LEFT JOIN inscriptions, GROUP BY étudiant, colonne nb_cours), en ne gardant que ceux ayant plus de 2 cours, triée par nb_cours décroissant puis par nom. La leçon explique comment lire son plan d'exécution avec EXPLAIN ANALYZE.
~30 minOptimisation
49
Données manquantes avancé
Par ville, calcule : le total d'etudiants (total), le nombre avec email (avec_email), le nombre sans email (sans_email) et le pourcentage d'emails renseignés (pct_complet, arrondi à 1 décimale). Astuce : compter une colonne précise ignore ses valeurs NULL. Groupe par ville.
~30 minNULL avancé
50
Analyse cohortes
Analyse par cohorte (ville + departement) : nb_etudiants, moyenne (AVG arrondie à 2 décimales), note_min, note_max. Ne garde que les groupes d'au moins 2 etudiants. Trie par moyenne décroissante.
~30 minAnalyse
51
Analyse de funnel — Conversion
Sur la table events (colonnes event_type, user_id), construis un funnel de conversion à 4 étapes : 'page_view' → 'signup' → 'first_order' → 'repeat_order'. Pour chaque étape affiche le libellé (step), le nombre d'utilisateurs distincts (users) et le taux de conversion en % par rapport à l'étape visite (conversion_pct).
~25 minAnalytics
52
Segmentation RFM
Sur la table orders (customer_id, order_date, price, quantity), calcule par client : la récence (jours depuis le dernier order_date), la fréquence (nb de commandes) et le montant (SUM(price*quantity)). Attribue un score NTILE(5) à chaque axe (r_score, f_score, m_score), puis un segment_label (Champions, Fideles, Nouveaux, A risque, Perdus, Autres). Trie par montant décroissant.
~25 minAnalytics
53
Analyse Year-over-Year
Sur la table orders, compare chaque mois de l'année en cours à la même période de l'année précédente : CA (revenue), nombre de commandes (orders) et panier moyen (avg_basket). Calcule la croissance du CA en % (revenue_growth_pct). Trie par mois.
~25 minAnalytics
54
Moving averages et tendances
Sur la table orders, calcule le CA quotidien puis sa moyenne mobile 7 jours (ma_7d) et 30 jours (ma_30d) avec des window frames ROWS. Ajoute une colonne trend valant 'hausse' si la MM7 dépasse la MM30, sinon 'baisse'. Trie par jour.
~20 minAnalytics
55
Metriques SaaS — MRR et churn
Sur la table subscriptions (customer_id, amount, period_start, status = 'active'), calcule par mois : le MRR total (total_mrr), le nouveau MRR (new_mrr), l'expansion (expansion_mrr), le churn (churned_mrr), la variation nette (net_mrr_change = new + expansion − churn − contraction) et le taux de churn en % (churn_rate_pct). Trie par mois.
~30 minAnalytics
56
JSONB — extraire des champs
La table events a une colonne payload de type JSONB (du JSON stocké en base). Pour chaque événement, extrais le navigateur et la plateforme, qui se trouvent dans payload → metadata. Colonnes : id, browser, platform. La leçon montre les opérateurs -> et ->>.
~20 minData Engineering
57
Expressions régulières — valider un format
Sur la table users (colonne email), affiche uniquement les emails au format valide, avec l'opérateur regex ~ : une partie locale, puis @, puis un nom de domaine, puis un point suivi d'une extension d'au moins 2 lettres. La leçon décompose le motif à utiliser.
~20 minData Engineering
58
Agrégats conditionnels — COUNT FILTER
Sur la table events, compte en une seule ligne le nombre d'événements de chaque type, avec un agrégat conditionnel (COUNT ... FILTER). Colonnes : page_views (type 'page_view'), signups (type 'signup'), purchases (type 'purchase').
~20 minAnalytics
59
Écart à la moyenne du groupe (fonction fenêtre)
Sur la table ventes, affiche pour chaque vente son écart au montant moyen de sa catégorie (colonne ecart_moyenne_cat, arrondie à 2 décimales), grâce à une fonction fenêtre par catégorie. Colonnes : produit, categorie, montant, ecart_moyenne_cat. Trie par categorie, puis montant décroissant.
~25 minWindow Functions
60
Projet final — Top 5 des produits qui rapportent le plus
Projet final : trouve les 5 produits qui rapportent le plus d'argent. La table order_items contient une ligne par produit commandé (colonnes product_id, quantity, price). Pour chaque produit (regroupe par product_id), calcule deux colonnes : total_quantite = la quantité totale vendue (somme de quantity), et chiffre_affaires = l'argent total généré (somme de quantity × price). Affiche seulement les 5 produits au plus gros chiffre_affaires, du plus grand au plus petit.
~30 minData Engineering

Envie d'aller plus loin ? Découvrez nos formations certifiées Bac+2 à Bac+5 →