行转列
Posted 张侦毅
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了行转列相关的知识,希望对你有一定的参考价值。
文章目录
使用场景
有时我们在进行图表数据统计时,在图表中,横轴为月份(英文大写),纵轴为图表数据。但是我们所使用的数据源表结构如下面的数据源
所示,而此时,下面的一条数据,其实就需要我们将其行转列,进行格式化,然后将数据显示在图表中。
当然,我们可以通过存储过程方法解决该问题,但是此处我并不推荐使用存储过程,因为由于业务的复杂性,我们在其它地方也可能会用到行转列后的数据的连表查询操作,而如果我们使用存储过程,这就意味着我们并不能再使用连表查询操作来处理存储过程了,而如果要在其它地方,仍然能够对行转列后的数据进行连表查询操作,这里我推荐使用视图方法。
数据源
建表语句如下:
CREATE TABLE `dept_data` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键id',
`name` varchar(64) DEFAULT NULL COMMENT '部门',
`year` int(10) DEFAULT NULL COMMENT '年份',
`month_1` double DEFAULT NULL COMMENT '一月数据',
`month_2` double DEFAULT NULL COMMENT '二月数据',
`month_3` double DEFAULT NULL COMMENT '三月数据',
`month_4` double DEFAULT NULL COMMENT '四月数据',
`month_5` double DEFAULT NULL COMMENT '五月数据',
`month_6` double DEFAULT NULL COMMENT '六月数据',
`month_7` double DEFAULT NULL COMMENT '七月数据',
`month_8` double DEFAULT NULL COMMENT '八月数据',
`month_9` double DEFAULT NULL COMMENT '九月数据',
`month_10` double DEFAULT NULL COMMENT '十月数据',
`month_11` double DEFAULT NULL COMMENT '十一月数据',
`month_12` double DEFAULT NULL COMMENT '十二月数据',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
在表中插入数据:
insert into `dept_data`(`id`,`name`,`year`,`month_1`,`month_2`,`month_3`,`month_4`,`month_5`,`month_6`,`month_7`,`month_8`,`month_9`,`month_10`,`month_11`,`month_12`) values (1,'部门1',2017,1,2,3,4,5,6,7,8,9,10,11,12),(2,'部门2',2018,1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8,9.9,10.1,11.11,12.12);
行转列
创建个月视图
创建一月份视图:
CREATE VIEW dept_data_month_01_view AS
SELECT
dd.`id`,
1 AS month_index,
dd.`name`,
STR_TO_DATE(CONCAT(dd.`year`, '-01'), '%Y-%m') AS DATE,
dd.year,
dd.`month_1` AS DATA
FROM
dept_data dd;
创建二月份视图
CREATE VIEW dept_data_month_02_view AS
SELECT
dd.`id`,
2 AS month_index,
dd.`name`,
STR_TO_DATE(CONCAT(dd.`year`, '-02'), '%Y-%m') AS DATE,
dd.year,
dd.`month_2` AS DATA
FROM
dept_data dd;
以此类推,创建各月视图,在这里,我就不一一展示其创建视图语句了。
将个月视图拼接成完整月度数据视图
当我们将所有月份的视图创建完成后,再将各月的视图拼接成一个完整的月度数据视图,其完整月度数据视图创建语句如下:
CREATE VIEW dept_data_month_view AS
SELECT * FROM dept_data_month_01_view
UNION ALL
SELECT * FROM dept_data_month_02_view
UNION ALL
SELECT * FROM dept_data_month_03_view
UNION ALL
SELECT * FROM dept_data_month_04_view
UNION ALL
SELECT * FROM dept_data_month_05_view
UNION ALL
SELECT * FROM dept_data_month_06_view
UNION ALL
SELECT * FROM dept_data_month_07_view
UNION ALL
SELECT * FROM dept_data_month_08_view
UNION ALL
SELECT * FROM dept_data_month_09_view
UNION ALL
SELECT * FROM dept_data_month_10_view
UNION ALL
SELECT * FROM dept_data_month_11_view
UNION ALL
SELECT * FROM dept_data_month_12_view
将完整月度数据视图进行格式化
由于我们最终是要将其展示在图表中的,而在图表中,横轴是大写的英文月份,因而我们又需要将行转列后的数据执行格式化操作。
CREATE VIEW dept_data_month_format_view AS
SELECT
ddmv.`id`,
ddmv.`month_index`,
ddmv.`name`,
ddmv.`year`,
ddmv.`DATE`,
CASE
WHEN DATE_FORMAT(ddmv.`date`, '%m') = 01
THEN 'Jan'
WHEN DATE_FORMAT(ddmv.`date`, '%m') = 02
THEN 'Feb'
WHEN DATE_FORMAT(ddmv.`date`, '%m') = 03
THEN 'Mar'
WHEN DATE_FORMAT(ddmv.`date`, '%m') = 04
THEN 'Apr'
WHEN DATE_FORMAT(ddmv.`date`, '%m') = 05
THEN 'May'
WHEN DATE_FORMAT(ddmv.`date`, '%m') = 06
THEN 'Jun'
WHEN DATE_FORMAT(ddmv.`date`, '%m') = 07
THEN 'Jul'
WHEN DATE_FORMAT(ddmv.`date`, '%m') = 08
THEN 'Aug'
WHEN DATE_FORMAT(ddmv.`date`, '%m') = 09
THEN 'Sep'
WHEN DATE_FORMAT(ddmv.`date`, '%m') = 10
THEN 'Oct'
WHEN DATE_FORMAT(ddmv.`date`, '%m') = 11
THEN 'Nov'
WHEN DATE_FORMAT(ddmv.`date`, '%m') = 12
THEN 'Dec'
END month_format,
ddmv.`DATA`
FROM dept_data_month_view ddmv ORDER BY ddmv.`month_index` ASC
图表展示效果
最终在图表中的展示效果(2018年):
计算月度平均值
创建月度数据平均值视图
而如果我们要统计每个月的平均值,如下:
月份 | 平均值 |
---|---|
一月 | 1月份数据除以1 |
二月 | 1、2月份数据之和除以2 |
三月 | 1、2、3月份数据之和除以3 |
… | … |
此时,月度数据平均值视图创建语句如下:
CREATE VIEW dept_data_month_format_target_view AS
SELECT
ddmfv.`id`,
ddmfv.`month_index`,
ddmfv.`name`,
ddmfv.`year`,
ddmfv.`DATE`,
ddmfv.`month_format`,
(SELECT
SUM(ddmfv2.DATA)
FROM
dept_data_month_format_view ddmfv2
WHERE ddmfv2.DATE <= ddmfv.`DATE`
AND ddmfv2.name = ddmfv.`name`) / ddmfv.`month_index` month_average
FROM
dept_data_month_format_view ddmfv
ORDER BY ddmfv.month_index ASC
图表展示效果
结合图表一中的数据,其最终的展示结果如下:
当我们将鼠标指针指上去时,我们可以看到当前月份所展示的数据值:
以上是关于行转列的主要内容,如果未能解决你的问题,请参考以下文章