Aller au contenu
Agrégations

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

Modèle
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

Exemple concret
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

  1. 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.
  2. Pour un montant conditionnel : SUM(CASE WHEN p.category = 'Audio' THEN oi.quantity * p.price ELSE 0 END).
  3. 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.
  4. 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