Filtrez après agrégation avec HAVING et pivotez vos données avec CASE WHEN dans les fonctions d'agrégat.
Ouvrir cette leçon dans KodokonVous maîtrisez déjà GROUP BY. Ce module attaque ce qui distingue une requête correcte d'une requête professionnelle : filtrage post-agrégation, agrégats conditionnels, et la connaissance fine de l'ordre d'évaluation. Pour pratiquer, ouvrez sqliteonline.com (moteur SQLite) ou lancez sqlite3 dans un terminal : chaque leçon fournit les CREATE TABLE et INSERT nécessaires. Copiez ce jeu de données avant d'exécuter les exemples.
CREATE TABLE orders (
id INTEGER PRIMARY KEY,
customer TEXT NOT NULL,
category TEXT NOT NULL,
amount REAL NOT NULL,
status TEXT NOT NULL
);
INSERT INTO orders (customer, category, amount, status)
VALUES
('alice', 'books', 42.0, 'paid'),
('alice', 'games', 55.0, 'paid'),
('alice', 'books', 18.5, 'refunded'),
('bruno', 'games', 70.0, 'paid'),
('bruno', 'books', 12.0, 'paid'),
('chloe', 'games', 95.0, 'paid'),
('chloe', 'books', 30.0, 'paid'),
('david', 'books', 8.0, 'refunded');L'ordre logique d'évaluation est la clé : FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY. WHERE filtre des lignes avant le regroupement ; HAVING filtre des groupes après le calcul des agrégats. C'est pourquoi WHERE SUM(amount) > 90 est illégal : au moment du WHERE, aucune somme n'existe encore. Ici, on ne garde que les clients dont le total payé dépasse 90 (attendu : alice et chloe).
SELECT customer,
COUNT(*) AS nb_orders,
SUM(amount) AS total
FROM orders
WHERE status = 'paid'
GROUP BY customer
HAVING SUM(amount) > 90;Deuxième pattern indispensable : l'agrégat conditionnel. En glissant un CASE WHEN dans SUM ou COUNT, vous calculez plusieurs indicateurs en une seule passe sur la table, là où un débutant enchaînerait trois requêtes. C'est la technique standard pour pivoter des lignes en colonnes.
SELECT customer,
SUM(CASE WHEN category = 'books'
THEN amount ELSE 0 END) AS books_total,
SUM(CASE WHEN category = 'games'
THEN amount ELSE 0 END) AS games_total
FROM orders
WHERE status = 'paid'
GROUP BY customer;