Pokud jste měli známý počet hodnot pro obě order
a item
, pak byste mohli natvrdo zakódovat dotaz do:
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;
Viz Ukázka . Ale součástí problému, který budete mít, je to, že se pokoušíte transformovat více sloupců dat. Můj návrh, jak získat konečný výsledek, by bylo nejprve odklopit data. MySQL nemá funkci unpivot, ale můžete použít UNION ALL pro převod několika párů sloupců na řádky. Kód pro unpivot bude podobný následujícímu:
select id, concat('order', `order`) col, data value
from tableA
union all
select id, concat('item', item) col, price value
from tableA;
Viz Ukázka . Výsledkem bude:
| ID | COL | VALUE |
-----------------------
| 1 | order1 | P |
| 1 | order1 | P |
| 1 | order1 | P |
| 1 | item1 | 50 |
| 1 | item2 | 60 |
| 1 | item3 | 70 |
Jak můžete vidět, zabralo to několik sloupců order
/data
a item
/price
a převést jej do více řádků. Po dokončení můžete hodnoty převést zpět na sloupce pomocí agregační funkce s 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;
Viz Ukázka . Nakonec je třeba převést výše uvedený kód na dynamicky připravený příkazový dotaz:
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;
Viz SQL Fiddle s ukázkou . Výsledkem je:
| ID | ORDER1 | ORDER2 | ORDER3 | ITEM1 | ITEM2 | ITEM3 | ITEM4 |
-------------------------------------------------------------------
| 1 | P | Q | (null) | 50 | 60 | 70 | (null) |
| 2 | P | (null) | S | 50 | 60 | (null) | 80 |