Chcete-li získat požadovaný výsledek, budete muset oba odklopit aktuální data ze sloupců do řádků a poté pivot year
data z řádků do sloupců.
MySQL nemá funkci PIVOT nebo UNPIVOT, takže budete muset použít UNION ALL
dotaz na unpivot a agregační funkci s CASE
výraz na pivot.
Pokud máte známý počet hodnot, můžete napevno zakódovat hodnoty podobné tomuto:
select locid,
event,
max(case when year = 2011 then value end) `2011`,
max(case when year = 2012 then value end) `2012`
from
(
select LocId, Year, 'Birth' event, Birth value
from yt
union all
select LocId, Year, 'Death' event, Death value
from yt
union all
select LocId, Year, 'Abc' event, Abc value
from yt
) d
group by locid, event;
Viz SQL Fiddle s ukázkou .
Ale pokud budete mít neznámý počet hodnot, pak budete muset použít připravený příkaz ke generování dynamického SQL. Kód bude podobný následujícímu:
SET @sql = NULL;
SET @sqlUnpiv = NULL;
SET @sqlPiv = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'select locid, year, ''',
c.column_name,
''' as event, ',
c.column_name,
' as value
from yt '
) SEPARATOR ' UNION ALL '
) INTO @sqlUnpiv
FROM information_schema.columns c
where c.table_name = 'yt'
and c.column_name not in ('LocId', 'Year')
order by c.ordinal_position;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'max(CASE WHEN year = ',
year,
' THEN value else null END) AS `',
year, '`'
)
) INTO @sqlPiv
FROM yt;
SET @sql
= CONCAT('SELECT locid,
event, ', @sqlPiv, '
from
( ', @sqlUnpiv, ' ) d
group by locid, event');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
Viz SQL Fiddle s ukázkou . Výsledek pro oba dotazy je:
| LOCID | EVENT | 2011 | 2012 |
-------------------------------
| 1 | Abc | 10 | 20 |
| 1 | Birth | 100 | 98 |
| 1 | Death | 60 | 70 |