希望する結果を得るには、両方のピボット解除を行う必要があります。 現在のデータを列から行に変換してから、year
をピボットします 行から列へのデータ。
MySQLにはPIVOTまたはUNPIVOT関数がないため、UNION ALL
を使用する必要があります ピボットを解除するクエリとCASE
を使用した集計関数 ピボットする式。
既知の数の値がある場合は、次のような値をハードコーディングできます。
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;
SQL Fiddle withDemo を参照してください。 。
ただし、値の数が不明な場合は、プリペアドステートメントを使用して動的SQLを生成する必要があります。コードは次のようになります:
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;
SQL Fiddle withDemo を参照してください。 。両方のクエリの結果は次のとおりです。
| LOCID | EVENT | 2011 | 2012 |
-------------------------------
| 1 | Abc | 10 | 20 |
| 1 | Birth | 100 | 98 |
| 1 | Death | 60 | 70 |