Agrégation conditionnelle
Placer un CASE dans un agrégat permet de calculer plusieurs indicateurs en un seul passage, un par colonne. C'est la technique du tableau croisé : une ligne par client, une colonne par statut.
- SUM CASE WHEN
- FILTER
- pivot
- tableau croisé
- COUNT CASE
Syntaxe
SELECT groupe, SUM(CASE WHEN condition THEN 1 ELSE 0 END) AS nb_cas, COUNT(*) FILTER (WHERE condition) AS nb_cas_bisFROM tableGROUP BY groupe;Exemple
SELECT c.name AS client, SUM(CASE WHEN o.status = 'livré' THEN 1 ELSE 0 END) AS livrees, SUM(CASE WHEN o.status = 'en cours' THEN 1 ELSE 0 END) AS en_cours, COUNT(*) FILTER (WHERE o.status = 'annulé') AS annuleesFROM customers cJOIN orders o ON o.customer_id = c.idGROUP BY c.id, c.nameORDER BY c.id;-- Jeu de données : boutique-- Résultat attendu :-- Lucas Martin | 1 | 1 | 0-- Emma Dubois | 1 | 0 | 0-- Hugo Lambert | 1 | 0 | 0-- Léa Moreau | 0 | 0 | 1À retenir
- La clause standard FILTER (WHERE …) est plus lisible que CASE : elle est acceptée par SQLite 3.30+ et PostgreSQL, mais pas par MySQL ni SQL Server, où CASE reste la forme portable.
- Pour un montant conditionnel : SUM(CASE WHEN p.category = 'Audio' THEN oi.quantity * p.price ELSE 0 END).
- Piège : sans ELSE, le CASE vaut NULL quand la condition est fausse. SUM ignore ces NULL et renvoie NULL, au lieu de 0, si aucune ligne ne correspond. Écrivez ELSE 0 dans un SUM.
- Variante sans ELSE qui reste juste : COUNT(CASE WHEN condition THEN 1 END), car COUNT ignore les NULL. SQLite accepte aussi SUM(o.status = 'livré'), une comparaison valant 0 ou 1, mais PostgreSQL le refuse.
Voir aussi
- COUNT & GROUP BYGROUP BY range les lignes en groupes selon une ou plusieurs colonnes, puis COUNT, SUM ou AVG calculent une valeur par groupe. On obtient un tableau de synthèse, une ligne par groupe.
- COALESCE & CASECASE introduit une logique « si… alors… sinon » dans une requête, COALESCE renvoie la première valeur non NULL. Ils servent à classer des lignes en catégories ou à remplacer une valeur manquante.
- SUM, AVG, MIN, MAXCes fonctions résument une colonne numérique en une seule valeur : total, moyenne, plus petite et plus grande valeur, sur toute la table ou par groupe. Base de tout indicateur chiffré.
- GROUP_CONCAT / string_aggGROUP_CONCAT assemble les valeurs d'un groupe en une seule chaîne séparée par un délimiteur. Pratique pour afficher la liste des élèves d'une classe ou des produits d'une commande sur une ligne.