Mysql 列转行(数据透视表)

标签 mysql sql pivot unpivot

我有一张这样的 table

+---+-----+----+----+----+----+
|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 没有这些函数,因此您需要使用 UNION ALL 查询来复制它们,并使用 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

SQL Fiddle with Demo .

结果:

|  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 |

然后您将其包装在一个子查询中以应用聚合和 CASE 将其转换为您想要的格式:

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

SQL Fiddle with demo

结果是:

| DESCRIP | JAN | FEB |
-----------------------
|    col1 |   A |   C |
|    col2 |   B |   A |
|    col3 |   0 |   G |
|    col4 |   B |   E |

关于Mysql 列转行(数据透视表),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13944417/

相关文章:

mysql - 为什么这个 INSERT INTO 语句不起作用?

php - 为什么这是模棱两可的?

sql - 如何按日期时间进行数据透视表或交叉表?

mysql - 在不知道密码的情况下授予对数据库的访问权限

MySQL - 更新连接自然顺序

php - Laravel pluck 返回 id 值 "0"

java - PrintWriter 在下一行打印

sql - 为什么我不能使用变量代替字符串作为参数

SQL Server动态PIVOT查询?

sql - 将 1 行表展平为键值对表