Bonjour à tous, c’est mon 1er post de l’année 2009, donc je vous souhaite à tous mes meilleurs voeux pour cette nouvelle année… Après 15 jours sans accés au réseau ( oui cela m’arrive une fois l’an ) me voila de retour en ligne. Comme le signalait arnaud, j’espère rencontrer le maximum de personne à Paris pour la soirée Open Source. En attendant, faisons un peu de MySQL!
La question du jour m’a été posée par mon ami Geoff et c’est une question assez simple. Comment mettre les differentes valeurs d’une colonne sur une ligne?
Sans rentrer dans les détails, nous avons une simple table qui stocke différents métrics mesurés sur plusieurs serveurs. Nous avons à faire une application de monitoring.
mysql> desc default_summary;
+—————+——————+——+—–+———+—————-+
| Field | Type | Null | Key | Default | Extra |
+—————+——————+——+—–+———+—————-+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| host | char(25) | NO | MUL | | |
| date | datetime | NO | MUL | | |
| metric1 | float | YES | | NULL | |
| metric2 | float | YES | | NULL | |
mysql> select host,date, metric1 from default_summary limit 5;
| host1 | 2009-11-06 17:00:00 | 5 |
| host2 | 2009-11-06 17:00:00 | 6 |
| host3 | 2009-11-06 17:00:00 | 7 |
Ce que mon ami aimerait avoir est:
| 2009-11-06 17:00:00 | 5 | 6 | 7 |
Donc comment arriver à ce résultat sans passer pas des tables temporaires, qui est aussi une solution dans certains cas?
select date
sum( case host when ‘host1′ then metric1 else 0 end ) as host1,
sum( case host when ‘host2′ then metric1 else 0 end ) as host2,
sum( case host when ‘host3′ then metric1 else 0 end ) as host3,
….
from default_summary
group by date;
Il faut évidemment connaitre tous les valeurs de host dés le début… humm je sens que je vais bientôt coder une petite fonction
Il y a plusieurs solutions possibles sous d’autre SGBD comme Oracle ( PL/SQL, SYS_CONNECT_BY_PATH, Oracle Cross Join ) mais ceci est une autre histoire!
Mots-clefs : pratique