SQL : le PIVOT / UNPIVOT

Comment simplement transposer des lignes et des colonnes en langage SQL ? C’est ce que nous vous proposons de découvrir dans cet article.

Dans le monde des bases de données relationnelles, les données sont structurées de manière tabulaires par construction. Cependant, les besoins analytiques imposent souvent une représentation différente. En reporting par exemple, il est fréquent d’attendre des résultats sous forme de tableaux croisés, avec des indicateurs répartis en colonnes plutôt qu’en lignes. Par conséquent, transposer des lignes en colonnes (ou l’inverse) est l’une des transformations souvent nécessaire. C’est précisément le rôle des opérateurs PIVOT et UNPIVOT. Bien maitriser ces fonctions offre un gain de temps considérable et permet d’éviter les empilements de requêtes complexes et difficiles à maintenir.

Supposons les données de ventes suivantes :

Ce modèle est idéal pour l’enregistrement des transactions, mais peu lisible pour une analyse comparative.

La fonction PIVOT

La fonction PIVOT permet de transposer les valeurs présentées en lignes en colonnes distinctes, en appliquant une fonction d’agrégation (SUM,COUNT,AVG…).

Syntaxe générale :

SELECT <colonnes_non_pivotées>, <colonnes_pivotées>
FROM ( <requête_source> ) AS source
PIVOT (
    <fonction_agregation>(<colonne_valeur>)
    FOR <colonne_pivot>
    IN ( <liste_valeurs> )
) AS pivot_table;

NB: Une fonction d’agrégation est obligatoire. Et les valeurs pivotées doivent être connues à l’avance.

Pour notre cas exemple :

Faire pivoter la colonne produit (qui contient les valeurs A et B) revient à faire:

SELECT annee, A, B
FROM ventes
PIVOT (
    SUM(montant)
    FOR produit IN ([A], [B])
) AS p
ORDER BY annee;

Résultat :

On retrouve bien un tableau croisé qui permet de comparer le produit A et le produit B d’année en année.

La fonction UNPIVOT

La fonction UNPIVOT fait l’opération inverse : elle transpose des colonnes en lignes.

Objectif: À partir d’un tableau croisé, retrouver une structure ligne par ligne exploitable par des traitements standards.

Syntaxe générale :

SELECT
    <colonnes_non_dépivotées>,<colonne_noms_pivot>,<colonne_valeurs>
FROM
    ( <requête_source> ) AS source
UNPIVOT	
(
    <colonne_valeurs>
    FOR <colonne_noms_pivot>
    IN ( <colonne_pivot_1>, <colonne_pivot_2>, ... )
) AS unpivot_table
[ ORDER BY ... ];

Exemple :

SELECT annee, produit, montant
FROM ventes_pivot
UNPIVOT (
montant FOR produit IN ([A], [B])
) AS u;

Résultat :

Les noms de colonnes deviennent des valeurs présentées en lignes.

Différences entre SGBD : une fonctionnalité non standard

Contrairement aux clauses SQL classiques (SELECT, JOIN, GROUP BY), les fonctions PIVOT et UNPIVOT ne font pas partie du standard SQL. Leur disponibilité et leur syntaxe varient donc fortement selon le SGBD utilisé.

SGDBPIVOTUNPIVOTCommentaire
Microsoft SQL ServerExisteExisteSyntaxe propriétaire, largement utilisée
Oracle DBExisteExisteSupport natif et complet
IBM DB2N’existe pasN’existe pasImplémentation via CASE WHEN ou UNION ALL
PostgreSQLN’existe pasN’existe pasAlternatives via CASE WHEN ou crosstab()
MySQL / MariaDBN’existe pasN’existe pasCASE WHEN recommandé

Impact sur la portabilité

L’utilisation de PIVOT ou UNPIVOT rend les requêtes dépendantes du SGBD, ce qui peut poser problème dans des environnements multi-bases et des projets de migration.

Pour garantir une meilleure portabilité, il peut être préférable d’utiliser des alternatives qui offrent un comportement équivalent et fonctionnent sur l’ensemble des bases de données.

En l’absence de support natif de PIVOT et UNPIVOT dans certains SGBD, l’utilisation de solutions alternatives permet de reproduire le même comportement tout en garantissant une portabilité maximale des requêtes SQL.

Alternative universelle – PIVOT compatible toutes bases) : le CASE WHEN

SELECT
  annee,
  SUM(CASE WHEN produit = 'A' THEN montant END) AS A,
  SUM(CASE WHEN produit = 'B' THEN montant END) AS B
FROM ventes
GROUP BY annee
ORDER BY annee;

Résultat :

Alternative universelle – UNPIVOT compatible toutes bases : UNION ALL

SELECT annee, 'A' AS produit, A AS montant
FROM ventes_pivot
UNION ALL
SELECT annee, 'B', B
FROM ventes_pivot
ORDER BY annee, produit;

Résultat :

Conclusion

Les fonctions PIVOT et UNPIVOT sont des outils puissants pour transformer la structure des données SQL. Bien utilisées, elles simplifient considérablement la création de rapports et améliorent la lisibilité des résultats. Elles doivent toutefois être employées avec discernement, notamment sur de gros volumes et dans des environnement multi-bases.

guest
0 Commentaires
Le plus ancien
Le plus récent
Commentaires en ligne
Afficher tous les commentaires