Intermédiaire

Exercices — Séance 4

Quatre parties progressives : CTEs, window functions, LAG avec dashboard, et jointures.

Contexte commun

Base de données de ventes, VentesRepository et dashboard Streamlit des séances précédentes. Tables disponibles : ventes, clients et produits.

Méthode de travail

Pour chaque partie, testez vos requêtes SQL avec pd.read_sql_query() avant de les intégrer dans le repository puis dans le dashboard Streamlit.

Exercice : Partie A — CTEs

Facile

Créez une méthode get_categories_vs_moyenne() dans votre repository.

Objectif

Afficher les catégories de produits avec leur CA total et leur position par rapport à la moyenne des catégories.

Étapes

  1. CTE ca_par_categorie : calculez le CA total par catégorie de produit.
sql
WITH ca_par_categorie AS (
    SELECT categorie, SUM(montant) AS chiffre_affaires
    FROM ventes
    GROUP BY categorie
)
  1. CTE moyenne_categories : calculez la moyenne du CA des catégories à partir de la première CTE.

  2. SELECT final : joignez les deux CTEs pour retourner chaque catégorie avec :

    • Son chiffre_affaires
    • La moyenne globale
    • Un statut : « Au-dessus » ou « En-dessous »
  3. Intégration Streamlit : créez un bar chart coloré par statut avec une ligne horizontale fig.add_hline() pour la moyenne.

Critères de validation

  • La requête utilise au moins deux CTEs chaînées
  • Le résultat inclut le champ statut calculé avec CASE WHEN
  • Le graphique affiche la ligne de moyenne en pointillés
  • use_container_width=True

Exercice : Partie B — Window functions

Moyen

Créez une méthode get_top_clients_par_segment(top_n=5) dans votre repository.

Objectif

Pour chaque segment client, afficher les N clients avec le CA le plus élevé, avec leur rang.

Étapes

  1. CTE ca_par_client : calculez le CA total par client (vous avez besoin d'une jointure ventes JOIN clients).
sql
WITH ca_par_client AS (
    SELECT
        c.id,
        c.nom,
        c.segment,
        SUM(v.montant) AS chiffre_affaires
    FROM ventes v
    INNER JOIN clients c ON v.client_id = c.id
    GROUP BY c.id, c.nom, c.segment
)
  1. CTE avec_rang : ajoutez un RANK() partitionné par segment et ordonné par CA décroissant.

  2. SELECT final : filtrez les lignes où rang <= top_n.

  3. Intégration Streamlit : utilisez px.bar() avec facet_col="segment" pour afficher un sous-graphique par segment.

Critères de validation

  • La requête utilise RANK() avec PARTITION BY segment
  • Le paramètre top_n est variable (pas hardcodé)
  • Le graphique utilise facet_col pour séparer les segments
  • Les clients sont triés par rang dans chaque sous-graphique

Exercice : Partie C — LAG et dashboard

Moyen

Créez une méthode get_evolution_par_categorie(annee) et intégrez-la dans un dashboard à deux colonnes.

Objectif

Pour chaque catégorie de produit, afficher l'évolution mensuelle du CA avec la comparaison au mois précédent.

Étapes

  1. CTE ca_mensuel_categorie : calculez le CA mensuel par catégorie.
sql
WITH ca_mensuel_categorie AS (
    SELECT
        strftime('%Y-%m', date_vente) AS mois,
        categorie,
        SUM(montant) AS chiffre_affaires
    FROM ventes
    WHERE strftime('%Y', date_vente) = '2024'
    GROUP BY strftime('%Y-%m', date_vente), categorie
)
  1. CTE avec_evolution : utilisez LAG() avec PARTITION BY categorie ORDER BY mois pour récupérer le CA du mois précédent par catégorie.

  2. SELECT final : calculez l'évolution absolue et en pourcentage. Gérez la division par zéro.

  3. Dashboard Streamlit :

    • Colonne gauche : line chart du CA mensuel par catégorie (une courbe par catégorie, utiliser color="categorie")
    • Colonne droite : bar chart de l'évolution % par mois (utiliser un st.selectbox() pour choisir la catégorie)

Critères de validation

  • LAG() utilise PARTITION BY categorie pour isoler chaque catégorie
  • La division par zéro est gérée avec CASE WHEN
  • Le dashboard contient deux colonnes avec st.columns(2)
  • Le selectbox filtre dynamiquement le graphique d'évolution
  • fig.add_hline(y=0) sur le graphique d'évolution

Exercice : Partie D — Jointures et synthèse

Difficile

Créez une vue analytique combinant jointures, CTEs, window functions et LAG.

Objectif

Créer un tableau de bord « Analyse par segment client » avec :

  • Le CA par segment avec classement
  • L'évolution mensuelle par segment
  • Le top 3 produits par segment

Étapes

  1. Méthode get_analyse_segment() : une seule requête SQL combinant :
    • JOIN ventes + clients + produits
    • CTE d'agrégation par segment
    • RANK() pour le classement des segments
    • LAG() pour l'évolution mensuelle
sql
WITH ventes_enrichies AS (
    SELECT
        v.montant,
        v.date_vente,
        c.segment,
        p.nom AS produit_nom,
        p.categorie
    FROM ventes v
    INNER JOIN clients c ON v.client_id = c.id
    INNER JOIN produits p ON v.produit_id = p.id
),
-- ... ajoutez vos CTEs ici
  1. Dashboard Streamlit : organisez la page avec :
    • Un st.metric() par segment (CA + delta)
    • Un bar chart horizontal du classement des segments
    • Un graphique d'évolution temporelle
    • Un tableau st.dataframe() avec le top 3 produits par segment

Critères de validation

  • La requête utilise au moins une jointure, deux CTEs, une window function et LAG()
  • Les st.metric() affichent le delta par rapport au mois précédent
  • Le layout utilise st.columns() pour organiser les graphiques
  • Tous les graphiques ont des labels lisibles et use_container_width=True

À retenir

Progression

  • Partie A : maîtriser les CTEs pour structurer des requêtes avec calculs intermédiaires
  • Partie B : utiliser RANK() avec PARTITION BY pour des classements par groupe
  • Partie C : combiner LAG() et PARTITION BY pour des comparaisons temporelles par catégorie
  • Partie D : synthèse — jointures, CTEs, window functions et LAG dans un dashboard