最近在开发过程中遇到问题,需要将数据库中一张表信息进行行转列操作,再将每列(即每个字段)作为与其他表进行联表查询的字段进行显示。
借此机会,在网上查阅了相关方法,现总结出一种比较简单易懂的方法备用。
普通查询
select id, data_time, num
from test
where id = 1
order by data_time;
运行结果:
行数据转为列数据
当我们想把id为1的数据按照时间排列在一行,那么这时候就需要用到group by了,当然了,这里用的函数不一定是sum
select id,
sum(if(date_format(DATA_TIME, '%H:%i') = '11:23', num, null)) as d1,
sum(if(date_format(DATA_TIME, '%H:%i') = '11:24', num, null)) as d2,
sum(if(date_format(DATA_TIME, '%H:%i') = '11:25', num, null)) as d3
from test
group by id;
查询结果:
总结
可以看出,这里行转列是将原来的data_time字段的多行内容选出来,作为结果集中的不同列,并根据id进行分组显示对应的num;
注意点:
1.SUM()是为了能够使用GROUP BY根据id进行分组,因为每一个id对应的data_time=‘某个时间’ 的记录只有一条,所以SUM()的值就等于对应那一条记录的num的值。
假如id=1 和data_time=‘某个时间’ 的记录有两条,则此时SUM()的值将会是这两条记录的和,同理,使用Max()的值将会是这两条记录里面值最大的一个。但是正常情况下,一个id对应一个时间段下的数据只有一个,因此可以使用SUM()、MAX()、MIN()、AVG()等聚合函数都可以达到行转列的效果。
建表语句
-- auto-generated definition
create table test
(
id int not null,
data_time datetime not null,
num int null
);
数据语句
INSERT INTO `test`(`id`, `data_time`, `num`) VALUES (1, '2023-06-20 11:24:00', 1);
INSERT INTO `test`(`id`, `data_time`, `num`) VALUES (1, '2023-06-20 11:25:00', 54);
INSERT INTO `test`(`id`, `data_time`, `num`) VALUES (1, '2023-06-20 11:23:00', 5234);