我有一张这样的表
+---+-----+----+----+----+----+
|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 |
+----+---+---+
任何人都可以帮忙吗?
答案 0 :(得分:38)
您需要做的是先疏散数据然后转动数据。但遗憾的是,MySQL没有这些功能,所以你需要使用UNION ALL
查询对于unpivot进行复制,并使用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 |
然后将其包装在子查询中以应用聚合,并将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
结果是:
| DESCRIP | JAN | FEB |
-----------------------
| col1 | A | C |
| col2 | B | A |
| col3 | 0 | G |
| col4 | B | E |
答案 1 :(得分:0)
尽管这个问题很古老并且有人将其标记为“非常常见”,但人们似乎仍然发现它(包括我在内)并认为它很有帮助。我开发了一种更通用的版本,可以取消对行的透视,并认为这可能对某人有所帮助。
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, key, value
结果结构。