Aide-mémoire SQL : les 16 notions essentielles
Mis à jour le · 16 notions · exemples testés avec SQLite
Cet aide-mémoire SQL réunit les 16 notions utilisées dans SpeedQL, de SELECT aux CTE récursives. Pour chacune : une définition courte, un conseil et un exemple de requête. Les exemples utilisent des tables simples (staff, customers, orders…) et la syntaxe de SQLite, le moteur SQL du jeu.
Ordre d’écriture d’une requête SQL
Les clauses d’une requête s’écrivent toujours dans cet ordre (seules SELECT et FROM sont obligatoires) :
SELECT … FROM … JOIN … ON … WHERE … GROUP BY … HAVING … ORDER BY … LIMIT …SELECT, alias, DISTINCT
À quoi servent SELECT, AS et DISTINCT en SQL ?
SELECT choisit les colonnes à afficher ; AS renomme une colonne, DISTINCT retire les doublons.
Conseil : Liste les colonnes utiles plutôt que SELECT * : le résultat est plus lisible et plus rapide.
Exemple de requête
SELECT DISTINCT department AS dept
FROM staff;S’entraîner : exercices SQL sur SELECT, alias, DISTINCT (4 questions) · voir 4 exercices corrigés
WHERE (filtres)
À quoi sert WHERE en SQL ?
WHERE garde les lignes qui respectent une condition : =, <>, >, BETWEEN, IN, LIKE, AND, OR, NOT.
Conseil : Les textes et les dates s’écrivent entre apostrophes : department = 'IT'.
Exemple de requête
SELECT name
FROM staff
WHERE salary > 40000 AND department IN ('IT', 'HR');S’entraîner : exercices SQL sur WHERE (filtres) (31 questions) · voir 15 exercices corrigés
ORDER BY, LIMIT
Comment trier et limiter un résultat SQL avec ORDER BY et LIMIT ?
ORDER BY trie (ASC croissant, DESC décroissant) ; LIMIT garde les n premières lignes.
Conseil : Ajoute une deuxième colonne de tri pour départager les égalités.
Exemple de requête
SELECT name, salary
FROM staff
ORDER BY salary DESC, name
LIMIT 3;S’entraîner : exercices SQL sur ORDER BY, LIMIT (7 questions) · voir 6 exercices corrigés
COUNT, SUM, AVG, MIN, MAX
À quoi servent COUNT, SUM, AVG, MIN et MAX en SQL ?
Les agrégats résument plusieurs lignes en une valeur : COUNT, SUM, AVG, MIN, MAX.
Conseil : COUNT(*) compte les lignes ; COUNT(colonne) ignore les valeurs NULL.
Exemple de requête
SELECT COUNT(*), ROUND(AVG(salary), 1), MAX(salary)
FROM staff;S’entraîner : exercices SQL sur COUNT, SUM, AVG, MIN, MAX (7 questions) · voir 3 exercices corrigés
GROUP BY
À quoi sert GROUP BY en SQL ?
GROUP BY calcule un résumé par groupe : une ligne de résultat par valeur de la colonne.
Conseil : Toute colonne affichée sans agrégat doit apparaître dans le GROUP BY.
Exemple de requête
SELECT department, COUNT(*)
FROM staff
GROUP BY department;S’entraîner : exercices SQL sur GROUP BY (27 questions) · voir 15 exercices corrigés
JOIN
Qu’est-ce qu’un JOIN en SQL ?
JOIN relie deux tables par une colonne commune ; LEFT JOIN garde aussi les lignes sans correspondance.
Conseil : Donne un alias court à chaque table (c, o) et précise toujours la condition ON.
Exemple de requête
SELECT c.name, o.amount
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id;Les types de jointure
- INNER JOIN (ou simplement JOIN) : garde seulement les lignes qui ont une correspondance dans les deux tables.
- LEFT JOIN : garde toutes les lignes de la table de gauche ; les colonnes de droite valent NULL quand il n’y a pas de correspondance.
- RIGHT JOIN et FULL JOIN : l’inverse du LEFT JOIN, et la réunion des deux. SQLite ne les accepte que depuis sa version 3.39 ; un LEFT JOIN avec les tables inversées donne le même résultat qu’un RIGHT JOIN.
- CROSS JOIN : toutes les combinaisons de lignes des deux tables (produit cartésien), sans condition ON.
Pour trouver les lignes sans correspondance, par exemple les clients qui n’ont jamais commandé, combine LEFT JOIN et IS NULL :
SELECT c.name
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
WHERE o.id IS NULL;S’entraîner : exercices SQL sur JOIN (60 questions) · voir 15 exercices corrigés
HAVING
Quelle est la différence entre HAVING et WHERE en SQL ?
HAVING filtre les groupes après GROUP BY (WHERE, lui, filtre les lignes avant).
Conseil : Une condition sur COUNT, SUM ou AVG va dans HAVING, jamais dans WHERE.
Exemple de requête
SELECT department, AVG(salary)
FROM staff
GROUP BY department
HAVING COUNT(*) >= 3;WHERE ou HAVING : l’ordre d’exécution
Une requête ne s’exécute pas dans l’ordre où elle s’écrit : FROM et JOIN d’abord, puis WHERE, GROUP BY, HAVING, SELECT, ORDER BY et enfin LIMIT. WHERE agit donc avant la formation des groupes, sur chaque ligne ; HAVING agit après, sur les groupes et leurs agrégats. C’est aussi pourquoi, en SQL standard, un alias défini dans SELECT ne peut pas servir dans WHERE (SQLite le tolère, mais la plupart des autres bases le refusent).
Les deux se combinent : WHERE écarte d’abord des lignes, puis HAVING filtre les groupes obtenus.
SELECT department, COUNT(*)
FROM staff
WHERE salary > 30000
GROUP BY department
HAVING COUNT(*) >= 3;S’entraîner : exercices SQL sur HAVING (20 questions) · voir 12 exercices corrigés
Sous-requêtes
Qu’est-ce qu’une sous-requête SQL ?
Une sous-requête est une requête dans une requête : une valeur, une liste (IN) ou une table.
Conseil : Écris d’abord la sous-requête seule pour vérifier son résultat, puis intègre-la.
Exemple de requête
SELECT name
FROM staff
WHERE salary > (SELECT AVG(salary) FROM staff);S’entraîner : exercices SQL sur Sous-requêtes (34 questions) · voir 15 exercices corrigés
CASE
À quoi sert CASE en SQL ?
CASE choisit une valeur selon des conditions, ligne par ligne.
Conseil : Les conditions sont testées dans l’ordre : la première vraie l’emporte.
Exemple de requête
SELECT name, CASE WHEN salary >= 45000 THEN 'high' ELSE 'standard' END AS band
FROM staff;S’entraîner : exercices SQL sur CASE (25 questions) · voir 15 exercices corrigés
NULL, COALESCE
Comment gérer les valeurs NULL en SQL ?
NULL = valeur absente : on la teste avec IS NULL / IS NOT NULL ; COALESCE la remplace.
Conseil : col = NULL ne marche jamais : il faut écrire col IS NULL.
Exemple de requête
SELECT name, COALESCE(city, 'unknown')
FROM contacts
WHERE email IS NULL;S’entraîner : exercices SQL sur NULL, COALESCE (11 questions) · voir 14 exercices corrigés
UNION, INTERSECT, EXCEPT
À quoi servent UNION, INTERSECT et EXCEPT en SQL ?
UNION réunit deux résultats (sans doublon), INTERSECT garde ce qu’ils ont en commun, EXCEPT retire le second du premier.
Conseil : Les deux requêtes doivent renvoyer le même nombre de colonnes.
Exemple de requête
SELECT member
FROM chess
INTERSECT SELECT member
FROM music;S’entraîner : exercices SQL sur UNION, INTERSECT, EXCEPT (13 questions) · voir 11 exercices corrigés
Texte et dates
Comment manipuler du texte et des dates en SQL ?
Textes et dates : UPPER, LOWER, LENGTH, SUBSTR, ||, LIKE, strftime, julianday, date.
Conseil : Dans LIKE, % remplace n’importe quelle suite de caractères et _ un seul caractère.
Exemple de requête
SELECT UPPER(name), strftime('%Y', hired)
FROM staff
WHERE name LIKE 'A%';S’entraîner : exercices SQL sur Texte et dates (24 questions) · voir 15 exercices corrigés
CTE (WITH)
Qu’est-ce qu’une CTE (WITH) en SQL ?
WITH donne un nom à une requête intermédiaire, qu’on réutilise ensuite comme une table.
Conseil : Plusieurs CTE se suivent, séparées par des virgules, avant le SELECT final.
Exemple de requête
WITH d AS (
SELECT department, AVG(salary) AS m
FROM staff
GROUP BY department)
SELECT *
FROM d
WHERE m > 40000;S’entraîner : exercices SQL sur CTE (WITH) (31 questions) · voir 15 exercices corrigés
EXISTS
À quoi sert EXISTS en SQL ?
EXISTS est vrai si la sous-requête renvoie au moins une ligne ; NOT EXISTS, si elle n’en renvoie aucune.
Conseil : NOT EXISTS est plus sûr que NOT IN quand la sous-requête peut contenir des NULL.
Exemple de requête
SELECT c.name
FROM customers c
WHERE NOT EXISTS (SELECT 1 FROM orders o WHERE o.customer_id = c.id);S’entraîner : exercices SQL sur EXISTS (22 questions) · voir 15 exercices corrigés
Fonctions de fenêtre (OVER)
Qu’est-ce qu’une fonction de fenêtre (OVER) en SQL ?
Les fonctions de fenêtre calculent sur un groupe de lignes sans les regrouper : ROW_NUMBER, RANK, DENSE_RANK, LAG, LEAD, SUM() OVER…
Conseil : PARTITION BY découpe les groupes, ORDER BY fixe l’ordre à l’intérieur de chaque groupe.
Exemple de requête
SELECT name, salary, RANK() OVER (PARTITION BY department ORDER BY salary DESC)
FROM staff;ROW_NUMBER, RANK ou DENSE_RANK ?
Les trois numérotent les lignes selon l’ORDER BY de la fenêtre ; ils ne diffèrent qu’en cas d’égalité. Pour des salaires de 50 000, 45 000, 45 000 et 40 000 :
- ROW_NUMBER : 1, 2, 3, 4 (un numéro unique, les ex æquo sont départagés arbitrairement) ;
- RANK : 1, 2, 2, 4 (même rang pour les ex æquo, puis un saut) ;
- DENSE_RANK : 1, 2, 2, 3 (même rang, sans saut).
LAG et LEAD lisent la valeur de la ligne précédente ou suivante ; SUM() OVER (ORDER BY …) calcule un cumul. Une fonction de fenêtre ne peut pas apparaître dans WHERE : pour garder la première ligne de chaque groupe, calcule le rang dans une CTE, puis filtre dessus.
WITH r AS (
SELECT name, department,
ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) AS n
FROM staff
)
SELECT name, department FROM r WHERE n = 1;S’entraîner : exercices SQL sur Fonctions de fenêtre (OVER) (111 questions) · voir 15 exercices corrigés
CTE récursives
Qu’est-ce qu’une CTE récursive en SQL ?
Une CTE récursive s’appelle elle-même pour générer une suite ou parcourir une hiérarchie. Toujours prévoir une condition d’arrêt.
Conseil : Une partie de départ, UNION ALL, puis la partie qui se rappelle avec un WHERE qui s’arrête.
Exemple de requête
WITH RECURSIVE n(x) AS (
SELECT 1
UNION ALL SELECT x + 1
FROM n
WHERE x < 5)
SELECT x
FROM n;S’entraîner : exercices SQL sur CTE récursives (18 questions) · voir 11 exercices corrigés
SQLite, PostgreSQL, MySQL : les différences à connaître
Quelles sont les différences entre SQLite, PostgreSQL et MySQL ?
Les requêtes de cet aide-mémoire s’écrivent presque à l’identique dans les trois bases. Les écarts portent surtout sur les dates, la concaténation de texte, la division et quelques jointures. Voici ceux qui piègent le plus souvent quand on passe de SpeedQL (SQLite) à une autre base.
| Point | SQLite | PostgreSQL | MySQL |
|---|---|---|---|
| Concaténer du texte | a || b | a || b | CONCAT(a, b) (|| veut dire OR) |
| Année d’une date | strftime('%Y', d) | EXTRACT(YEAR FROM d) | YEAR(d) |
Division 7 / 2 | 3 (entiers) | 3 (entiers) | 3.5000 |
| LIKE et la casse | insensible (lettres ASCII) | sensible (ILIKE pour l’ignorer) | selon la collation, souvent insensible |
| FULL OUTER JOIN | oui, depuis la version 3.39 | oui | non : UNION d’un LEFT et d’un RIGHT JOIN |
| Booléens | 0 et 1 | type BOOLEAN (true / false) | BOOLEAN = TINYINT(1) |
| Types des colonnes | souples (affinité de type) | stricts | stricts, avec conversions implicites |
| Clé auto-incrémentée | INTEGER PRIMARY KEY | GENERATED ALWAYS AS IDENTITY | AUTO_INCREMENT |
Conseil : SELECT, WHERE, JOIN, GROUP BY, HAVING, les sous-requêtes, les CTE et les fonctions de fenêtre sont standard : ce que tu pratiques dans SpeedQL se réutilise tel quel dans PostgreSQL et MySQL 8.
Passer à la pratique
Le meilleur moyen de retenir ces notions est de les utiliser. Lance une partie chronométrée de SQL, choisis une notion dans les exercices SQL personnalisés ou relève l’exercice SQL du jour.
Pour pratiquer en jouant, découvre aussi notre sélection des meilleurs jeux SQL et comment ils se comparent.