Para obtener el resultado que desea, deberá despivotar los datos actuales de las columnas a las filas y luego girar el year
datos de filas a columnas.
MySQL no tiene una función PIVOT o UNPIVOT, por lo que deberá usar UNION ALL
consulta para anular el pivote y una función agregada con un CASE
expresión para pivotar.
Si tiene una cantidad conocida de valores, puede codificar valores similares a este:
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;
Consulte SQL Fiddle con demostración .
Pero si va a tener un número desconocido de valores, necesitará usar una declaración preparada para generar SQL dinámico. El código será similar al siguiente:
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;
Consulte SQL Fiddle con demostración . El resultado de ambas consultas es:
| LOCID | EVENT | 2011 | 2012 |
-------------------------------
| 1 | Abc | 10 | 20 |
| 1 | Birth | 100 | 98 |
| 1 | Death | 60 | 70 |