Mysql将列转换为行(透视表)
我有一张这样的桌子Mysql将列转换为行(透视表),mysql,sql,pivot,unpivot,Mysql,Sql,Pivot,Unpivot,我有一张这样的桌子 +---+-----+----+----+----+----+ |id |month|col1|col2|col3|col4| +---+-----+----+----+----+----+ |101|Jan |A |B |NULL|B | +---+-----+----+----+----+----+ |102|feb |C |A |G |E | +---+-----+----+----+----+----+ +----+---+---+
+---+-----+----+----+----+----+
|id |month|col1|col2|col3|col4|
+---+-----+----+----+----+----+
|101|Jan |A |B |NULL|B |
+---+-----+----+----+----+----+
|102|feb |C |A |G |E |
+---+-----+----+----+----+----+
+----+---+---+
|desc|jan|feb|
+----+---+---+
|col1|A |C |
+----+---+---+
|col2|B |A |
+----+---+---+
|col3|0 |G |
+----+---+---+
|Col4|B |E |
+----+---+---+
然后我想创建这样的报告
+---+-----+----+----+----+----+
|id |month|col1|col2|col3|col4|
+---+-----+----+----+----+----+
|101|Jan |A |B |NULL|B |
+---+-----+----+----+----+----+
|102|feb |C |A |G |E |
+---+-----+----+----+----+----+
+----+---+---+
|desc|jan|feb|
+----+---+---+
|col1|A |C |
+----+---+---+
|col2|B |A |
+----+---+---+
|col3|0 |G |
+----+---+---+
|Col4|B |E |
+----+---+---+
有人能帮上忙吗?您需要做的是首先解除数据锁定,然后再进行数据透视。但不幸的是,MySQL没有这些函数,因此您需要使用unpivot的UNION-ALL查询和pivot的带有CASE的聚合函数来复制它们 unpivot或UNION ALL片段从col1、col2等中获取数据,并将其转换为多行:
select id, month, col1 value, 'col1' descrip
from yourtable
union all
select id, month, col2 value, 'col2' descrip
from yourtable
union all
select id, month, col3 value, 'col3' descrip
from yourtable
union all
select id, month, col4 value, 'col4' descrip
from yourtable
看
结果:
| ID | MONTH | VALUE | DESCRIP |
----------------------------------
| 101 | Jan | A | col1 |
| 102 | feb | C | col1 |
| 101 | Jan | B | col2 |
| 102 | feb | A | col2 |
| 101 | Jan | (null) | col3 |
| 102 | feb | G | col3 |
| 101 | Jan | B | col4 |
| 102 | feb | E | col4 |
然后将其包装在子查询中以应用聚合,并将其转换为所需的格式:
select descrip,
max(case when month = 'jan' then value else 0 end) jan,
max(case when month = 'feb' then value else 0 end) feb
from
(
select id, month, col1 value, 'col1' descrip
from yourtable
union all
select id, month, col2 value, 'col2' descrip
from yourtable
union all
select id, month, col3 value, 'col3' descrip
from yourtable
union all
select id, month, col4 value, 'col4' descrip
from yourtable
) src
group by descrip
看
结果是:
| DESCRIP | JAN | FEB |
-----------------------
| col1 | A | C |
| col2 | B | A |
| col3 | 0 | G |
| col4 | B | E |
虽然这个问题已经很老了,而且有人把它标记为非常常见的问题,但人们似乎仍然觉得它包括我在内,而且很有用。我开发了一个更通用的版本来取消一行,并认为它可能会对某些人有所帮助
SET @target_schema='schema';
SET @target_table='table';
SET @target_where='`id`=1';
SELECT
GROUP_CONCAT(qry SEPARATOR ' UNION ALL ')
INTO @sql
FROM (
SELECT
CONCAT('SELECT `id`,', QUOTE(COLUMN_NAME), ' AS `key`,`', COLUMN_NAME, '` AS `value` FROM `', @target_table, '` WHERE ', @target_where) qry
FROM (
SELECT `COLUMN_NAME`
FROM `INFORMATION_SCHEMA`.`COLUMNS`
WHERE `TABLE_SCHEMA`=@target_schema
AND `TABLE_NAME`=@target_table
) AS `A`
) AS `B`;
PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
我在MySQL 8.x服务器上使用此查询,并将其聚合到一个JSON对象,从而得到id、键、值结果结构。欢迎使用stackoverflow。请花几分钟时间搜索档案。首先尝试调整前面的一个答案。然后,如果您遇到问题,请在此处发布您的查询和任何错误。可能重复的,谢谢!非常有帮助。非常感谢。如果您的表是来自子查询的派生表,该怎么办。我是否要将每个yourtable替换为类似于FROM SELECT*FROM table,其中name='condition't1?@accounterم是的,这正是您想要的do@Taryn-你的解决方案太棒了。这对我帮助很大。投票赞成你的惊人答案。