我试着搜索帖子,但我只找到SQL Server/Access的解决方案。我需要一个解决方案在MySQL (5.X)。
我有一个表(称为历史)3列:hostid, itemname, itemvalue。
如果我执行select (select * from history),它会返回
+--------+----------+-----------+
| hostid | itemname | itemvalue |
+--------+----------+-----------+
| 1 | A | 10 |
+--------+----------+-----------+
| 1 | B | 3 |
+--------+----------+-----------+
| 2 | A | 9 |
+--------+----------+-----------+
| 2 | C | 40 |
+--------+----------+-----------+
如何查询数据库以返回类似的内容
+--------+------+-----+-----+
| hostid | A | B | C |
+--------+------+-----+-----+
| 1 | 10 | 3 | 0 |
+--------+------+-----+-----+
| 2 | 9 | 0 | 40 |
+--------+------+-----+-----+
我找到了一种方法,使用简单的查询使我的报告几乎动态地将行转换为列。你可以在这里在线查看和测试。
查询的列数是固定的,但值是动态的,并且基于行值。所以,我使用一个查询来构建表头,另一个查询来查看值:
SELECT distinct concat('<th>',itemname,'</th>') as column_name_table_header FROM history order by 1;
SELECT
hostid
,(case when itemname = (select distinct itemname from history a order by 1 limit 0,1) then itemvalue else '' end) as col1
,(case when itemname = (select distinct itemname from history a order by 1 limit 1,1) then itemvalue else '' end) as col2
,(case when itemname = (select distinct itemname from history a order by 1 limit 2,1) then itemvalue else '' end) as col3
,(case when itemname = (select distinct itemname from history a order by 1 limit 3,1) then itemvalue else '' end) as col4
FROM history order by 1;
你也可以总结一下:
SELECT
hostid
,sum(case when itemname = (select distinct itemname from history a order by 1 limit 0,1) then itemvalue end) as A
,sum(case when itemname = (select distinct itemname from history a order by 1 limit 1,1) then itemvalue end) as B
,sum(case when itemname = (select distinct itemname from history a order by 1 limit 2,1) then itemvalue end) as C
FROM history group by hostid order by 1;
+--------+------+------+------+
| hostid | A | B | C |
+--------+------+------+------+
| 1 | 10 | 3 | NULL |
| 2 | 9 | NULL | 40 |
+--------+------+------+------+
RexTester测试结果:
http://rextester.com/ZSWKS28923
作为一个实际使用的例子,下面的报告以列的形式显示了船只/公共汽车出发和到达的时间,并有一个可视化的时间表。你会看到一个额外的列没有使用在最后一个col而不会混淆可视化:
**票务系统的在线售票和存在
SELECT
hostid,
sum( if( itemname = 'A', itemvalue, 0 ) ) AS A,
sum( if( itemname = 'B', itemvalue, 0 ) ) AS B,
sum( if( itemname = 'C', itemvalue, 0 ) ) AS C
FROM
bob
GROUP BY
hostid;
如果你可以使用MariaDB,有一个非常非常简单的解决方案。
自MariaDB-10.02以来,添加了一个新的存储引擎CONNECT,可以帮助我们将另一个查询或表的结果转换为数据透视表,就像你想要的那样:
你可以看看这些文件。
首先安装connect存储引擎。
现在我们的表的主列是itemname,每一项的数据都位于itemvalue列中,所以我们可以使用这个查询得到结果数据透视表:
create table pivot_table
engine=connect table_type=pivot tabname=history
option_list='PivotCol=itemname,FncCol=itemvalue';
现在我们可以从数据透视表中选择我们想要的:
select * from pivot_table
详情请点击这里