ProgrammationDéveloppeur Backend

Comment réaliser une agrégation conditionnelle en SQL (par exemple, calculer les sommes par différents statuts dans un seul résultat) et quels pièges y a-t-il ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

L'agrégation conditionnelle est utilisée lorsqu'il est nécessaire d'agréger des valeurs (par exemple, la somme ou le nombre) selon différentes conditions dans le cadre d'une seule requête. Historiquement, pour atteindre de tels objectifs, les développeurs SQL devaient écrire de multiples sous-requêtes ou effectuer des jointures et des regroupements séparément pour chaque catégorie, ce qui conduisait à un code moins lisible et moins performant.

Le problème résidait dans la difficulté de calculer simultanément plusieurs agrégats avec différentes conditions — chaque agrégat nécessite généralement un filtrage, et l'application simple de SUM() ou COUNT() ne prend pas en compte la condition requise à l'intérieur de la fonction d'agrégation.

Solution — utiliser la construction CASE à l'intérieur de la fonction d'agrégation, ce qui permet de "séparer" les agrégats selon différentes conditions à la volée, sans avoir recours à plusieurs jointures :

Exemple de code :

SELECT department, SUM(CASE WHEN status = 'approved' THEN amount ELSE 0 END) AS approved_sum, SUM(CASE WHEN status = 'pending' THEN amount ELSE 0 END) AS pending_sum, COUNT(CASE WHEN status = 'rejected' THEN 1 END) AS rejected_count FROM payments GROUP BY department;

Caractéristiques clés :

  • Permet d'agréger selon plusieurs conditions simultanément dans une seule requête.
  • Fonctionne dans tous les dialectes SQL (le support syntaxique exact peut varier).
  • Peut être utilisé non seulement avec SUM, mais aussi avec COUNT, AVG, etc.

Questions pièges.

Peut-on se passer de la construction CASE pour l'agrégation conditionnelle ?

Une réponse incorrecte serait d'utiliser WHERE directement dans la requête avec la fonction d'agrégation. En réalité, WHERE filtre les lignes avant l'agrégation, et non à l'intérieur de chaque colonne agrégée.

Exemple de code (méthode incorrecte) :

SELECT COUNT(*) FROM payments WHERE status = 'approved'; SELECT COUNT(*) FROM payments WHERE status = 'pending';

Ces requêtes ne peuvent pas être combinées en une seule ligne de résultat selon différentes conditions sans CASE.

Que se passe-t-il si l'on utilise NULL dans l'expression conditionnelle ?

Si CASE ne renvoie pas de valeur alternative, elle sera par défaut NULL, et la fonction d'agrégation ignorera NULL.

Exemple de code :

SUM(CASE WHEN status = 'approved' THEN amount END) -- Si le statut n'est pas 'approved', alors NULL, et la ligne est ignorée dans SUM

Peut-on utiliser IF à la place de CASE ?

Dans certains dialectes SQL (par exemple, MySQL), c'est possible, mais ce code devient non portable entre différentes bases de données. Dans les requêtes universelles, utilisez toujours CASE.

Erreurs courantes et anti-modèles

  • Utiliser WHERE au lieu de la logique imbriquée à l'intérieur de CASE entraîne la nécessité de faire de multiples requêtes simples, ce qui dégrade les performances.
  • Oublier de définir ELSE 0 dans CASE peut conduire à un nombre/somme incorrect en raison des valeurs NULL omises.
  • Copier-coller CASE sans vérification adéquate entraîne des erreurs logiques et des calculs incorrects.

Exemple de la vie réelle

Cas négatif

Un analyste a tenté de calculer des sommes par statut en écrivant plusieurs sous-requêtes séparées. Le rapport externe est devenu complexe, et l'ajout de nouveaux statuts a nécessité de réécrire le code à chaque fois.

Avantages :

  • Facile à mettre en œuvre pour une seule métrique. Inconvénients :
  • Difficile à mettre à l'échelle, faible performance et répétabilité du code.

Cas positif

Un développeur a utilisé CASE dans une seule requête générale, créant un rapport universel avec la possibilité d'élargir pour de nouveaux statuts par une simple modification d'une requête.

Avantages :

  • Haute lisibilité, facilité d'évolutivité, performance. Inconvénients :
  • Nécessite la connaissance de la syntaxe CASE et de ses nuances dans différents SGBD.