Aller au contenu

Agrégations simples & avancées

·2 mins·
SQL Formation
SQL - Cet article fait partie d'une série.
Partie 4: Cet article

📌 Agrégations classiques
#

SELECT
  client_id,
  COUNT(*) AS nb_commandes,
  SUM(montant) AS total,
  AVG(montant) AS moyenne_total
FROM commandes
GROUP BY client_id;

⚠️ WHERE vs HAVING
#

ClauseSert à…S’utilise quand ?
WHEREFiltrer les lignes avant l’agrégationSur des colonnes
HAVINGFiltrer les groupes après l’agrégationSur des agrégats
-- Clients avec au moins 5 commandes
SELECT client_id, COUNT(*) AS nb
FROM commandes
GROUP BY client_id
HAVING COUNT(*) >= 5;

🧼 FILTER – Appliquer une agrégation conditionnelle
#

💡 Très pratique pour éviter les CASE WHEN dans les SUM/COUNT.

SELECT
  client_id,
  COUNT(*) AS nb_total,
  COUNT(*) FILTER (WHERE montant > 100) AS nb_grandes_commandes
FROM commandes
GROUP BY client_id;

Plus lisible que :

COUNT(CASE WHEN montant > 100 THEN 1 ELSE NULL END)

🧮 GROUPING SETS / ROLLUP / CUBE
#

Permet de faire plusieurs agrégations d’un coup (comme un UNION automatique).

  • GROUPING SETS

    SELECT region, produit, SUM(montant)
    FROM ventes
    GROUP BY GROUPING SETS (
      (region, produit),
      (region),
      (produit),
      ()
    );
    

    👉 Ça fait 4 agrégations :

    • par région & produit
    • par région
    • par produit
    • total général
  • ROLLUP : Cas particulier de GROUPING SETS, pour hiérarchie top-down.

    SELECT region, produit, SUM(montant)
    FROM ventes
    GROUP BY ROLLUP(region, produit);
    

    👉 Donne :

    • région + produit
    • région seule
    • total général
  • CUBE : Combine toutes les combinaisons possibles des colonnes groupées.

    SELECT region, produit, SUM(montant)
    FROM ventes
    GROUP BY CUBE(region, produit);
    

    👉 Donne :

    • region + produit
    • region seule
    • produit seul
    • total général

🧯 Pièges à éviter
#

⚠️ Piège✅ Solution
HAVING au lieu de WHERE (ou inversement)Réserve HAVING aux valeurs calculées
Ambiguïtés avec ROLLUP, GROUPING SETSUtilise GROUPING() pour savoir si une ligne est un total
Agrégation sur des NULLs inattendusUtilise COALESCE pour te protéger

🏋️‍♂️ Entraînement
#

  • Pour chaque client, afficher :
    • nombre de commandes
    • total des montants
    • nombre de commandes > 100
  • N’afficher que les clients avec au moins 2 commandes > 200
  • Regrouper les ventes par produit et region, avec un total général
  • Afficher tous les regroupements possibles (produit, region, global) avec CUBE
duckdb.sql("""
SELECT
  client_id,
  COUNT(*) AS total,
  COUNT(*) FILTER (WHERE montant > 100) AS nb_grandes_commandes
FROM commandes
GROUP BY client_id
HAVING COUNT(*) >= 2;
""").df()

📚 Ressources utiles
#

Thibault CLEMENT - Intechnia
Auteur
Thibault CLEMENT - Intechnia
Data scientist
SQL - Cet article fait partie d'une série.
Partie 4: Cet article