Si vous aviez un nombre connu de valeurs pour les deux order
et item
, vous pouvez alors coder en dur la requête dans :
select id,
max(case when `order` = 1 then data end) order1,
max(case when `order` = 2 then data end) order2,
max(case when `order` = 3 then data end) order3,
max(case when item = 1 then price end) item1,
max(case when item = 2 then price end) item2,
max(case when item = 3 then price end) item3,
max(case when item = 4 then price end) item4
from tableA
group by id;
Voir Démo . Mais une partie du problème que vous allez rencontrer est que vous essayez de transformer plusieurs colonnes de données. Ma suggestion pour obtenir le résultat final serait de d'abord désorienter les données. MySQL n'a pas de fonction unpivot mais vous pouvez utiliser un UNION ALL pour convertir les multiples paires de colonnes en lignes. Le code pour annuler le pivot sera similaire à ce qui suit :
select id, concat('order', `order`) col, data value
from tableA
union all
select id, concat('item', item) col, price value
from tableA;
Voir Démo . Le résultat sera :
| ID | COL | VALUE |
-----------------------
| 1 | order1 | P |
| 1 | order1 | P |
| 1 | order1 | P |
| 1 | item1 | 50 |
| 1 | item2 | 60 |
| 1 | item3 | 70 |
Comme vous pouvez le voir, cela a pris les multiples colonnes de order
/data
et item
/price
et convertissez-le en plusieurs lignes. Une fois cette opération terminée, vous pouvez reconvertir les valeurs en colonnes à l'aide d'une fonction d'agrégation avec un CASE :
select id,
max(case when col = 'order1' then value end) order1,
max(case when col = 'order2' then value end) order2,
max(case when col = 'order3' then value end) order3,
max(case when col = 'item1' then value end) item1,
max(case when col = 'item2' then value end) item2,
max(case when col = 'item3' then value end) item3
from
(
select id, concat('order', `order`) col, data value
from tableA
union all
select id, concat('item', item) col, price value
from tableA
) d
group by id;
Voir Démo . Enfin, vous devez convertir le code ci-dessus en une requête d'instruction préparée dynamique :
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'max(case when col = ''',
col,
''' then value end) as `',
col, '`')
) INTO @sql
FROM
(
select concat('order', `order`) col
from tableA
union all
select concat('item', `item`) col
from tableA
)d;
SET @sql = CONCAT('SELECT id, ', @sql, '
from
(
select id, concat(''order'', `order`) col, data value
from tableA
union all
select id, concat(''item'', item) col, price value
from tableA
) d
group by id');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
Voir SQL Fiddle avec démo . Cela donne un résultat :
| ID | ORDER1 | ORDER2 | ORDER3 | ITEM1 | ITEM2 | ITEM3 | ITEM4 |
-------------------------------------------------------------------
| 1 | P | Q | (null) | 50 | 60 | 70 | (null) |
| 2 | P | (null) | S | 50 | 60 | (null) | 80 |