Table_1
をExpected_Result_Table
にピボット解除する方法を知りたいのですが。
Table1
-----------------------------------------
Id abc brt ccc ddq eee fff gga hxx
-----------------------------------------
12345 0 1 0 5 0 2 0 0
21321 0 0 0 0 0 0 0 0
33333 2 0 0 0 0 0 0 0
41414 0 0 0 0 5 0 0 1
55001 0 0 0 0 0 0 0 2
60000 0 0 0 0 0 0 0 0
77777 9 0 3 0 0 0 0 0
Expected_Result_Table
---------------------
Id Word Qty>0
---------------------
12345 brt 1
12345 ddq 5
12345 fff 2
33333 abc 2
41414 eee 5
41414 hxx 1
55001 hxx 2
77777 abc 9
77777 ccc 3
では、0より大きい値のみを考慮して、Table_1
の列を転置してExpected_Result_Table
にする方法は?
MySQLにはUNPIVOT関数はありませんが、UNION ALL
を使用して列を行に変換できます。
基本的な構文は次のとおりです。
select id, Word, qty
from
(
select id, 'abc' Word, abc qty
from yt
where abc > 0
union all
select id, 'brt', brt
from yt
where brt > 0
) d
order by id;
あなたの場合、動的列のソリューションが必要であると述べています。その場合は、プリペアドステートメントを使用して動的SQLを生成する必要があります。
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'select id, ''',
c.column_name,
''' as Word, ',
c.column_name,
' as qty
from yt
where ',
c.column_name,
' > 0'
) SEPARATOR ' UNION ALL '
) INTO @sql
FROM information_schema.columns c
where c.table_name = 'yt'
and c.column_name not in ('id')
order by c.ordinal_position;
SET @sql
= CONCAT('select id, Word, qty
from
(', @sql, ') x order by id');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SQL Fiddle with Demo を参照してください
基本的に、データを列から行にピボット解除します。これには、UNIONALLを使用できます。フィルタは、ピボットされていないサブクエリ全体に適用することも、パーツに個別に適用することもできます。
select id, Word, Qty from
(
select id, 'abc' Word, abc Qty from table1
union all
select id, 'brt', brt from table1
union all
select id, 'ccc', ccc from table1
union all
select id, 'ddq', ddq from table1
union all
select id, 'eee', eee from table1
union all
select id, 'fff', fff from table1
union all
select id, 'gga', gga from table1
union all
select id, 'hxx', hxx from table1
) x
where Qty > 0
order by id;