Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql将列转换为行(透视表)_Mysql_Sql_Pivot_Unpivot - Fatal编程技术网

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-你的解决方案太棒了。这对我帮助很大。投票赞成你的惊人答案。