Le PIVOT / UNPIVOT est indispensable dès qu’on veut restructurer ses données, par exemple passer de lignes → colonnes (ou l’inverse). C’est l’équivalent SQL des pivot_table()
ou melt()
de pandas.
🔀 Module 6 – PIVOT & UNPIVOT#
🎯 Objectifs#
À la fin du module, tu sauras :
- Transformer des lignes en colonnes (
PIVOT
) - Aplatir des colonnes en lignes (
UNPIVOT
) - Réaliser manuellement un pivot si la fonction
PIVOT
n’existe pas dans ton SGBD - Appliquer ça à des cas concrets d’analyse
🔄 1. Pourquoi pivoter ?#
- Table longue → table large : voir chaque mois en colonne
- Préparer un jeu de données pour analyse, reporting, visualisation
- Se rapprocher de la structure utilisateur-friendly
📌 2. PIVOT (lignes → colonnes)#
La syntaxe dépend des SGBD. Voici 3 méthodes :
✅ Méthode 1 – PIVOT
natif (ex : SQL Server, DuckDB, Oracle)#
SELECT *
FROM (
SELECT client_id, mois, montant
FROM ventes
)
PIVOT (
SUM(montant)
FOR mois IN ('2024-01', '2024-02', '2024-03')
);
💡 Résultat : 1 ligne par client_id
, avec une colonne par mois.
✅ Méthode 2 – via CASE WHEN
(portable, fonctionne partout)#
SELECT
client_id,
SUM(CASE WHEN mois = '2024-01' THEN montant END) AS janv,
SUM(CASE WHEN mois = '2024-02' THEN montant END) AS fev,
SUM(CASE WHEN mois = '2024-03' THEN montant END) AS mars
FROM ventes
GROUP BY client_id;
🔁 Très utile quand PIVOT
n’est pas dispo (comme sur SQLite ou MySQL <8).
📌 3. UNPIVOT (colonnes → lignes)#
Moins courant, mais utile pour :
- Transformer une table large (ex : 1 colonne par mois) en longue
- Préparer une table pour des agrégations, ou du machine learning
✅ UNPIVOT explicite (ex : SQL Server, DuckDB)#
SELECT *
FROM ventes
UNPIVOT (
montant FOR mois IN (janv, fev, mars)
);
✅ UNPIVOT manuel avec UNION ALL
(portable)#
SELECT client_id, '2024-01' AS mois, janv AS montant FROM ventes
UNION ALL
SELECT client_id, '2024-02', fev FROM ventes
UNION ALL
SELECT client_id, '2024-03', mars FROM ventes;
🧯 4. Pièges à éviter#
⚠️ Piège | ✅ Solution |
---|---|
Trop de colonnes générées (pivot dynamique) | Filtrer les valeurs ou faire un PIVOT dynamique côté code |
Valeurs NULL après pivot | Utiliser COALESCE(..., 0) |
Mauvais agrégat (SUM , COUNT , etc.) | Bien préciser dans la clause PIVOT(...) |
🏋️♂️ 5. Exercices#
Exo 1 – Transformer une table de ventes (client_id, mois, montant) pour avoir une colonne par mois#
Exo 2 – Revenir à une table longue (client_id, mois, montant) depuis une table avec colonnes janv
, fev
, mars
#
Exo 3 – Créer un tableau croisé dynamique produit x mois avec SUM(montant)
en valeur#
🧰 6. Test rapide dans DuckDB (Python)#
duckdb.sql("""
SELECT *
FROM (
SELECT client_id, mois, montant
FROM ventes
)
PIVOT (
SUM(montant)
FOR mois IN ('2024-01', '2024-02', '2024-03')
)
""").df()