2012-12-19 4 views
9

J'ai une table comme celui-ciMysql Convertir la colonne à la ligne (Tableau croisé dynamique)

+---+-----+----+----+----+----+ 
|id |month|col1|col2|col3|col4| 
+---+-----+----+----+----+----+ 
|101|Jan |A |B |NULL|B | 
+---+-----+----+----+----+----+ 
|102|feb |C |A |G |E | 
+---+-----+----+----+----+----+ 

Et puis je veux créer un rapport comme celui-ci

+----+---+---+ 
|desc|jan|feb| 
+----+---+---+ 
|col1|A |C | 
+----+---+---+ 
|col2|B |A | 
+----+---+---+ 
|col3|0 |G | 
+----+---+---+ 
|Col4|B |E | 
+----+---+---+ 

Quelqu'un peut-il aider?

+0

Bienvenue sur stackoverflow. [Ceci est une question très commune] (http://stackoverflow.com/search?q= [mysql] + pivot). Veuillez prendre quelques minutes pour chercher dans les archives. Essayez d'adapter l'une des réponses précédentes en premier. Ensuite, si vous rencontrez des problèmes, postez votre requête et toute erreur ici. – Leigh

+0

duplication possible de [ligne de pivot MySQL en nombre dynamique de colonnes] (http://stackoverflow.com/questions/12004603/mysql-pivot-row-into-dynamic-number-of-columns) – RichardTheKiwi

Répondre

28

Ce que vous devez faire est d'abord, de faire pivoter les données, puis de les faire pivoter. Mais malheureusement, MySQL ne dispose pas de ces fonctions, vous devrez donc les répliquer en utilisant une requête UNION ALL pour l'unpivot et une fonction d'agrégat avec un CASE pour le pivot.

Le UNPIVOT ou UNION ALL pièce prend les données de votre col1, col2, etc et il se transforme en plusieurs lignes:

select id, month, col1 value, 'col1' descrip 
from yourtable 
union all 
select id, month, col2 value, 'col2' descrip 
from yourtable 
union all 
select id, month, col3 value, 'col3' descrip 
from yourtable 
union all 
select id, month, col4 value, 'col4' descrip 
from yourtable 

Voir SQL Fiddle with Demo.

Résultat:

| ID | MONTH | VALUE | DESCRIP | 
---------------------------------- 
| 101 | Jan |  A | col1 | 
| 102 | feb |  C | col1 | 
| 101 | Jan |  B | col2 | 
| 102 | feb |  A | col2 | 
| 101 | Jan | (null) | col3 | 
| 102 | feb |  G | col3 | 
| 101 | Jan |  B | col4 | 
| 102 | feb |  E | col4 | 

Vous Enveloppez ensuite ceci dans une sous-requête pour appliquer l'ensemble et la CASE pour convertir en le format que vous voulez:

select descrip, 
    max(case when month = 'jan' then value else 0 end) jan, 
    max(case when month = 'feb' then value else 0 end) feb 
from 
(
    select id, month, col1 value, 'col1' descrip 
    from yourtable 
    union all 
    select id, month, col2 value, 'col2' descrip 
    from yourtable 
    union all 
    select id, month, col3 value, 'col3' descrip 
    from yourtable 
    union all 
    select id, month, col4 value, 'col4' descrip 
    from yourtable 
) src 
group by descrip 

Voir SQL Fiddle with demo

Le le résultat est:

| DESCRIP | JAN | FEB | 
----------------------- 
| col1 | A | C | 
| col2 | B | A | 
| col3 | 0 | G | 
| col4 | B | E | 
+0

Merci pour cela! Super utile. –

+1

Merci beaucoup. Que se passe-t-il si 'yourtable' est une table dérivée issue d'une sous-requête. Est-ce que je vais remplacer chaque 'yourtable' par quelque chose comme' FROM (SELECT * FROM table WHERE name = 'condition') t1'? –

+1

@ Accountant م Oui, c'est exactement ce que vous feriez – Taryn

Questions connexes