Les fonctions d'agrégat SQL sont parmi les outils les plus utilisés dans l'analyse de données. Elles permettent de résumer des milliers de lignes en une seule valeur exploitable : total des ventes, nombre de clients actifs, panier moyen… Maîtriser SUM, COUNT, AVG, MIN et MAX est indispensable pour tout entretien data analyst.
Pourtant, ces fonctions recèlent des subtilités qui font trébucher même les candidats expérimentés. Comment COUNT(*) diffère-t-il de COUNT(colonne) ? Que se passe-t-il avec les valeurs NULL ? Comment combiner plusieurs agrégats dans une même requête ?
Cet article répond à toutes ces questions avec des exemples concrets, un tableau comparatif et des cas pratiques directement issus d'entretiens réels.
📌 Ce qu'il faut retenir
- Les 5 fonctions d'agrégat fondamentales sont
SUM,COUNT,AVG,MINetMAX COUNT(*)compte toutes les lignes,COUNT(colonne)ignore les valeursNULLAVGignore automatiquement lesNULL, ce qui peut fausser une moyenne attendue- Ces fonctions s'utilisent toujours avec
GROUP BYdès qu'une colonne non agrégée est présente dans leSELECT
Pourquoi les agrégats SQL sont incontournables en entretien
Dans un entretien data analyst, plus de 80 % des questions SQL impliquent au moins une fonction d'agrégat. Les recruteurs cherchent à vérifier que vous savez non seulement écrire la syntaxe correcte, mais aussi interpréter les résultats et anticiper les comportements inattendus.
Les agrégats servent à répondre à des questions métier concrètes : quel est le chiffre d'affaires mensuel ? Combien de commandes ont été passées par chaque client ? Quel est le produit le moins cher de chaque catégorie ? Ces questions reviennent systématiquement dans les tests techniques.
En combinant les agrégats avec GROUP BY et HAVING, vous pouvez construire des analyses puissantes en quelques lignes. Pour aller plus loin sur le GROUP BY, consultez notre guide complet sur GROUP BY et HAVING en SQL.
Les 5 fonctions d'agrégat fondamentales
SUM : calculer un total
SUM additionne toutes les valeurs non nulles d'une colonne numérique.
SELECT
categorie,
SUM(montant) AS chiffre_affaires
FROM commandes
GROUP BY categorie;
Cas d'usage typique : total des ventes par région, cumul des heures travaillées par employé, somme des coûts par projet.
COUNT : compter les lignes
COUNT existe sous deux formes aux comportements bien distincts.
-- Compte toutes les lignes (incluant les NULL)
SELECT COUNT(*) FROM clients;
-- Compte uniquement les lignes où email n'est pas NULL
SELECT COUNT(email) FROM clients;
Cette différence est au cœur de nombreuses questions d'entretien. Si votre table contient 1 000 clients dont 150 sans email renseigné, COUNT(*) retourne 1 000 et COUNT(email) retourne 850.
AVG : calculer une moyenne
AVG calcule la moyenne arithmétique en ignorant les valeurs NULL.
SELECT
departement,
AVG(salaire) AS salaire_moyen
FROM employes
GROUP BY departement;
⚠️ Attention
Si une colonne contient des NULL, AVG les exclut du calcul. Une colonne avec 10 valeurs dont 3 NULL donnera une moyenne basée sur 7 valeurs, pas 10. Ce comportement peut produire des résultats différents de ce qu'on obtiendrait en remplaçant les NULL par 0 avec COALESCE.
MIN et MAX : trouver les extrêmes
MIN et MAX retournent respectivement la valeur minimale et maximale d'une colonne. Ils fonctionnent sur les types numériques, mais aussi sur les dates et les chaînes de caractères.
SELECT
categorie,
MIN(prix) AS prix_min,
MAX(prix) AS prix_max,
MAX(prix) - MIN(prix) AS ecart
FROM produits
GROUP BY categorie;
Sur des chaînes, MIN et MAX utilisent l'ordre alphabétique (ou l'ordre du jeu de caractères). C'est particulièrement utile pour trouver la première et la dernière date d'activité d'un utilisateur.
Tableau comparatif des 5 fonctions
| Fonction | Rôle | Gestion des NULL | Types compatibles | Exemple d'usage |
|---|---|---|---|---|
SUM |
Somme totale | Ignorés | Numérique | Total des ventes |
COUNT(*) |
Nombre de lignes | Comptés | Tous | Nombre de commandes |
COUNT(col) |
Nombre de valeurs non nulles | Ignorés | Tous | Clients avec email |
AVG |
Moyenne arithmétique | Ignorés | Numérique | Panier moyen |
MIN |
Valeur minimale | Ignorés | Numérique, date, texte | Prix le plus bas |
MAX |
Valeur maximale | Ignorés | Numérique, date, texte | Dernière commande |
Combiner plusieurs agrégats dans une requête
En pratique, les entretiens demandent souvent de calculer plusieurs métriques simultanément. C'est là que les requêtes deviennent réellement intéressantes.
SELECT
categorie,
COUNT(*) AS nb_produits,
SUM(stock) AS stock_total,
AVG(prix) AS prix_moyen,
MIN(prix) AS prix_min,
MAX(prix) AS prix_max
FROM produits
WHERE actif = TRUE
GROUP BY categorie
HAVING COUNT(*) >= 5
ORDER BY stock_total DESC;
Cette requête répond en une seule passe à 5 questions métier. Le HAVING COUNT(*) >= 5 filtre les catégories avec moins de 5 produits, ce qui illustre la différence fondamentale entre WHERE (filtre avant agrégation) et HAVING (filtre après agrégation).
COUNT DISTINCT : compter les valeurs uniques
Une variante très fréquente en entretien est COUNT(DISTINCT colonne). Elle compte le nombre de valeurs distinctes non nulles.
SELECT
mois,
COUNT(DISTINCT client_id) AS clients_actifs,
COUNT(*) AS nb_commandes
FROM commandes
GROUP BY mois
ORDER BY mois;
La différence entre nb_commandes et clients_actifs donne immédiatement le nombre moyen de commandes par client actif. Ce type d'analyse est classique dans les exercices de taux de rétention utilisateur.
💡 Bon à savoir
Sur des tables de plusieurs millions de lignes, COUNT(DISTINCT colonne) peut être lent car il nécessite un tri ou un hachage interne. Sur PostgreSQL ou BigQuery, des fonctions d'approximation comme HLL_COUNT.DISTINCT ou approx_count_distinct offrent un résultat proche avec des performances bien meilleures.
Agrégats conditionnels avec FILTER et CASE WHEN
Une technique avancée très appréciée en entretien consiste à calculer des agrégats conditionnels, c'est-à-dire appliquer une fonction d'agrégat uniquement sur un sous-ensemble de lignes.
Avec CASE WHEN (compatible tous les moteurs SQL) :
SELECT
vendeur_id,
COUNT(*) AS total_ventes,
SUM(CASE WHEN statut = 'validee' THEN montant ELSE 0 END) AS ca_valide,
SUM(CASE WHEN statut = 'annulee' THEN 1 ELSE 0 END) AS nb_annulations
FROM ventes
GROUP BY vendeur_id;
Avec FILTER (syntaxe SQL standard, supportée par PostgreSQL) :
SELECT
vendeur_id,
COUNT(*) AS total_ventes,
SUM(montant) FILTER (WHERE statut = 'validee') AS ca_valide,
COUNT(*) FILTER (WHERE statut = 'annulee') AS nb_annulations
FROM ventes
GROUP BY vendeur_id;
La syntaxe FILTER est plus lisible et souvent plus performante sur PostgreSQL. Elle n'est cependant pas disponible sur MySQL ou SQL Server.
Les pièges classiques en entretien
Plusieurs erreurs reviennent systématiquement lors des tests techniques.
Oublier le GROUP BY : si vous utilisez une fonction d'agrégat et une colonne non agrégée dans le SELECT, vous devez lister cette colonne dans le GROUP BY. L'absence de GROUP BY génère une erreur sur la plupart des moteurs.
Confondre WHERE et HAVING : WHERE filtre les lignes avant le calcul des agrégats, HAVING filtre les groupes après. Utiliser WHERE avec une fonction d'agrégat provoque une erreur.
Ne pas anticiper les NULL : une colonne entièrement nulle retourne NULL (et non 0) pour SUM, AVG, MIN et MAX. Utilisez COALESCE(SUM(colonne), 0) pour retourner 0 dans ce cas.
Mélanger COUNT(*) et COUNT(colonne) sans y réfléchir : choisissez explicitement la forme adaptée à votre besoin.
Ces pièges sont directement liés aux questions des 20 questions SQL les plus posées en entretien, que nous vous recommandons de revoir avant un entretien.
Questions fréquentes
Quelle est la différence entre COUNT(*) et COUNT(1) ?
En pratique, COUNT(*) et COUNT(1) produisent le même résultat : ils comptent toutes les lignes incluant celles avec des NULL. Sur la plupart des moteurs modernes (PostgreSQL, MySQL, SQL Server), les optimiseurs génèrent le même plan d'exécution. Préférez COUNT(*) qui est la forme standard et la plus explicite.
Les fonctions d'agrégat fonctionnent-elles sans GROUP BY ?
Oui. Sans GROUP BY, la requête agrège l'intégralité de la table en une seule ligne. SELECT COUNT(*), SUM(montant), AVG(prix) FROM commandes retourne 1 ligne avec les métriques globales. Dès qu'on ajoute une colonne non agrégée dans le SELECT, le GROUP BY devient obligatoire.
Comment calculer une médiane en SQL ?
Il n'existe pas de fonction MEDIAN() standard en SQL. On utilise généralement les fonctions fenêtre PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY colonne) sur PostgreSQL et SQL Server, ou une construction avec ROW_NUMBER() et COUNT() sur MySQL. C'est une question avancée régulièrement posée en entretien senior.
SUM peut-il retourner une valeur négative ?
Oui, si la colonne contient des valeurs négatives. SUM additionne algébriquement toutes les valeurs non nulles, qu'elles soient positives ou négatives. C'est courant dans des colonnes représentant des ajustements, des remboursements ou des variations de stock.
Comment utiliser les agrégats avec les jointures ?
Les agrégats s'appliquent après les jointures. Il faut d'abord écrire les JOIN, puis le GROUP BY sur la colonne souhaitée. Attention à la duplication de lignes lors des jointures : un JOIN mal écrit peut multiplier les lignes et fausser un SUM ou un COUNT. Vérifiez toujours la granularité de votre résultat avant d'agréger.
Conclusion
Les fonctions d'agrégat SQL sont le fondement de toute analyse de données. Maîtriser SUM, COUNT, AVG, MIN et MAX — ainsi que leurs subtilités autour des NULL, du DISTINCT et des agrégats conditionnels — vous donne un avantage décisif en entretien.
La clé est de ne pas se contenter de mémoriser la syntaxe, mais de comprendre ce que chaque fonction fait réellement, ligne par ligne. Entraînez-vous sur des jeux de données contenant des NULL, des doublons et des cas limites pour développer ce réflexe.
Prêt à vous entraîner sur des exercices SQL complets avec correction détaillée ? Découvrez la plateforme SQL Pratique et testez vos requêtes directement dans le navigateur.
