Comment faire un tableau croisé dynamique avec MySQL

Publié le 26 Mai 2011

Autant être clair dès le début, cette fonctionnalité n'est pas (encore) présente dans MySQL.

 

Mais heureusement avec une requête SQL bien sentie un peu obtenir un résultat similaire.

 

Je vais partir d'une table qui contient les mêmes données que dans mon article concernant les tableaux croisés dynamique sous Excel à savoir:

 

Table ventes

mois client montant
janvier M.A. 2045
janvier M.A. 123
janvier B.H. 1034
janvier N.S. 765
janvier C.G. 34
janvier E.B. 983
fevrier M.A. 678
fevrier

B.H.

1254
fevrier N.S. 98
fevrier C.G. 459
fevrier E.B. 2451
février S.R. 34
mars B.H. 763
mars C.G. 896
mars E.B. 1439
mars S.R. 2392
mars S.R. 25

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

et le but est d'arriver au même résultat que sous excel:

 

+--------+---------+---------+------+
| client | janvier | fevrier | mars |
+--------+---------+---------+------+
| B.H    |    1034 |    1254 |  763 |
| C.G    |      34 |     459 |  896 |
| E.B    |     983 |    2451 | 1439 |
| M.A    |    2168 |     678 |    0 |
| N.S    |     765 |      98 |    0 |
| S.R    |       0 |      34 | 2417 |
+--------+---------+---------+------+

 

et pour y arriver voici la requête magique:

 

SELECT
   client,
   SUM(IF(mois = 'janvier', montant, 0)) AS janvier,
   SUM(IF(mois = 'fevrier', montant, 0)) AS fevrier,
   SUM(IF(mois = 'mars', montant, 0)) AS mars
FROM ventes
GROUP BY client;

 

Et oui grâce aux instructions IF on compte les ventes par mois (ce qui nous donne les différentes colonnes) et le GROUP BY permet de compter par client, ce qui nous donne bien le même résultat que sous Excel.

Rédigé par Bliz

Publié dans #MySQL

Repost0
Pour être informé des derniers articles, inscrivez vous :
Commenter cet article
P
Bonjour Bliz,<br /> J'ai le même besoin, mais dans mon cas, les mois sont remplacés par des machines.<br /> Le nombre de machines est variable.<br /> Je suis à cours d'idées...<br /> Merci pour vos suggestions :-)
Répondre
P
Voici le détail...<br /> <br /> la table d'entrée est de ce type:<br /> +--------------------+-----------------+-------------------+<br /> | DateTime | Probe | Temperature |<br /> +--------------------+-----------------+-------------------+<br /> | 24/01/2018 | 1 | 21.5 |<br /> +--------------------+-----------------+-------------------+<br /> | 24/01/2018 | 2 | 22.5 |<br /> +--------------------+-----------------+-------------------+<br /> | 24/01/2018 | 3 | 23.5 |<br /> +--------------------+-----------------+-------------------+<br /> | 25/01/2018 | 1 | 18.5 |<br /> +--------------------+-----------------+-------------------+<br /> | 25/01/2018 | 2 | 19.5 |<br /> +--------------------+-----------------+-------------------+<br /> | 25/01/2018 | 3 | 20.5 |<br /> +--------------------+-----------------+-------------------+<br /> | 26/01/2018 | 1 | 15.5 |<br /> +--------------------+-----------------+-------------------+<br /> | 26/01/2018 | 3 | 15.5 |<br /> +--------------------+-----------------+-------------------+<br /> | 27/01/2018 | 1 | 17.5 |<br /> +--------------------+-----------------+-------------------+<br /> | 27/01/2018 | 2 | 18.5 |<br /> +--------------------+-----------------+-------------------+<br /> <br /> <br /> <br /> la table en sortie devrait être de ce type:<br /> +---------------------+-----------------+-------------------+-------------------+<br /> | DateTime | Probe 1 | Probe 2 | Probe 3 |<br /> +---------------------+-----------------+-------------------+-------------------+<br /> | 24/01/2018 | 21.5 | 22.5 | 23.5 +<br /> +---------------------+-----------------+-------------------+-------------------+<br /> | 25/01/2018 | 18.5 | 19.5 | 20.5 +<br /> +---------------------+-----------------+-------------------+-------------------+<br /> | 26/01/2018 | 15.5 | | 15.5 +<br /> +---------------------+-----------------+-------------------+-------------------+<br /> | 27/01/2018 | 17.5 | 18.5 | +<br /> +---------------------+-----------------+-------------------+-------------------+
A
Salut, très interssant.<br /> Le soucis, si nous avons plusieurs ligne, disons 12 mois, n'existerais t'il pas une solution en lieu et place de :<br /> ....<br /> SUM(IF(mois = 'janvier', montant, 0)) AS janvier,<br /> SUM(IF(mois = 'janvier', montant, 0)) AS février,<br /> ...<br /> SUM(IF(mois = 'janvier', montant, 0)) AS décembre,<br /> ...<br /> Un peu fastidieux je dirais bien.
Répondre
B
Ou encore d'utiliser une procédure stockée mysql
B
Je ne connais pas de solution avec mysql directement.<br /> Après rien empêche de générer la requête par programmation depuis l'application cliente.
L
<br /> Merci pour cette astuce peu connue et qui (m') évite pas mal de lignes inutiles!<br />
Répondre
B
<br /> <br /> On peut également remplacer la fonction SUM() par AVG() pour avoir une moyenne ou MAX(), etc.<br /> <br /> <br /> S'il s'agit de texte (au lieu de nombres) il faut utiliser GROUP_CONCAT() par exemple.<br /> <br /> <br /> <br />
Répondre