MySql行转列&列转行方式

 更新时间:2024年11月05日 09:06:26   作者:江南春失忆梦i  
在MySQL数据库管理中,行转列和列转行是常见的数据处理需求,行转列通常涉及将表中的行数据按照某种规则转换成列形式,常用于报表生成、数据分析等场景,列转行则是将原本以列形式存储的数据转换成行形式,以便于进行进一步的数据处理或分析

MySql行转列&列转行

行转列

创建语句:

create table test1(
id int  auto_increment primary key ,
name varchar(255),
course varchar(255),
score int
)

insert into test1(name,course,score) values ('张三','语文',120);
insert into test1(name,course,score) values ('张三','数学',100);
insert into test1(name,course,score) values ('张三','英语',82);
insert into test1(name,course,score) values ('李四','语文',89);
insert into test1(name,course,score) values ('李四','数学',99);
insert into test1(name,course,score) values ('李四','英语',87);
insert into test1(name,course,score) values ('王五','语文',78);
insert into test1(name,course,score) values ('王五','数学',85);
insert into test1(name,course,score) values ('王五','英语',145);
insert into test1(name,course,score) values ('王五','物理',40);
insert into test1(name,course,score) values ('王五','化学',62);

原始数据:

1、第一种方法:

-- 使用case when then else,这里使用sum函数也可以
select name,
max(case course when '语文' then score else 0 end)as 'chinese',
max(case course when '数学' then score else 0 end)as 'math',
max(case course when '英语' then score else 0 end)as 'english',
max(case course when '物理' then score else 0 end)as 'wuli',
max(case course when '化学' then score else 0 end)as 'huaxue'
from test1 group by name

第一种结果:

2、第二种方法:

-- 使用if语句,这里使用sum函数也可以
select name,
max(if(course = '语文',score,0))as 'chinese',
max(if(course = '数学',score,0))as 'math',
max(if(course = '英语',score,0))as 'english',
max(if(course = '物理',score,0))as 'wuli',
max(if(course = '化学',score,0))as 'huaxue'
from test1 group by name

第二种结果:

3、第三种方法:

-- 动态拼接sql语句,不管多少行都会转列
set @sql = null;
select group_concat(distinct concat('max(if(a.course = ''',a.course,''', a.score, 0)) as ''',a.course, '''')) into @sql from test1 a;
set @sql = concat('select name,', @sql, 'from test1 a group by a.name' );
prepare stmt from @sql;  -- 动态生成脚本,预备一个语句
execute stmt;            -- 动态执行脚本,执行预备的语句
deallocate prepare stmt; -- 释放预备的语句 

-- 通过这个查询拼接的sql
select @sql

第三种结果:

查询出来的sql结果:

-- 查询出来的结果
select name,max(if(a.course = '语文', a.score, 0)) as '语文',max(if(a.course = '数学', a.score, 0)) as '数学',max(if(a.course = '英语', a.score, 0)) as '英语',max(if(a.course = '物理', a.score, 0)) as '物理',max(if(a.course = '化学', a.score, 0)) as '化学',max(if(a.course = '政治', a.score, 0)) as '政治'from test1 a group by a.name

4、第四种方法:

-- 使用distinct
select distinct  a.name,  
(select score from test1 b where a.name=b.name and b.course='语文' ) as 'chinese',  
(select score from test1 b where a.name=b.name and b.course='数学' ) as 'math',
(select score from test1 b where a.name=b.name and b.course='英语' ) as 'english',  
(select score from test1 b where a.name=b.name and b.course='物理' ) as 'wuli',  
(select score from test1 b where a.name=b.name and b.course='化学' ) as 'huaxue'  
from test1 a

第四种结果:

5、第五种方法:

以下三种方法是可以做统计的用的,有三种统计写法,有需求的话可以使用

-- 使用with rollup统计第一种
select ifnull(name,'总计') as name,
max(if(course = '语文',score,0))as 'chinese',
max(if(course = '数学',score,0))as 'math',
max(if(course = '英语',score,0))as 'english',
max(if(course = '物理',score,0))as 'wuli',
max(if(course = '化学',score,0))as 'huaxue',
sum(IF(course='total',score,0)) as 'total'
from (select name,ifnull(course,'total') as course,sum(score) as score
from test1 group by name, course with rollup having name is not null )as a group by name with rollup;


-- 使用with rollup与union all统计第二种
select name,
max(if(course = '语文',score,0))as 'chinese',
max(if(course = '数学',score,0))as 'math',
max(if(course = '英语',score,0))as 'english',
max(if(course = '物理',score,0))as 'wuli',
max(if(course = '化学',score,0))as 'huaxue',
sum(score) as total from test1 group by name
union all
select 'total',
max(if(course = '语文',score,0))as 'chinese',
max(if(course = '数学',score,0))as 'math',
max(if(course = '英语',score,0))as 'english',
max(if(course = '物理',score,0))as 'wuli',
max(if(course = '化学',score,0))as 'huaxue',
sum(score) from test1


-- 使用if与with rollup统计
select ifnull(name,'total') as name,
max(if(course = '语文',score,0))as 'chinese',
max(if(course = '数学',score,0))as 'math',
max(if(course = '英语',score,0))as 'english',
max(if(course = '物理',score,0))as 'wuli',
max(if(course = '化学',score,0))as 'huaxue',
sum(score) AS total 
from test1
group by name with rollup

第五种结果:

以上三种语句结果都是一样的

6、第六种方法:

-- 使用group_concat,这个一般不推荐
select name,
group_concat(course,':',score separator '@')as course
from test1 group by name

第六种结果:

7、第七中方法:

-- 这个也不推荐使用
set @EE='';
select @EE :=concat(@EE,'sum(if(course= \'',course,'\',score,0)) as ',course, ',') as aa from (select distinct course from test1) a ;
set @QQ = concat('select ifnull(name,\'total\')as name,',@EE,' sum(score) as total from test1 group by name with rollup');
-- SELECT @QQ;
prepare stmt from @QQ;
execute stmt;
deallocate prepare stmt;

第七种结果:

列转行

创建语句:

create table test2(
id int  auto_increment primary key ,
name varchar(255) ,
chinese int,
math int,
english int,
wuli int,
huaxue int
)

insert into test2(name,chinese,math,english,wuli,huaxue) values ('张三',110,120,85,null,null);
insert into test2(name,chinese,math,english,wuli,huaxue) values ('李四',130,88,89,null,null);
insert into test2(name,chinese,math,english,wuli,huaxue) values ('王五',93,124,87,98,67);

原始数据:

1、第一种方法:

有两种写法:

union与union all的区别就是:
union可以去除重复结果集,union all不会去除重复的结果集  
-- 第一种使用union实现列传行
select name,'语文' as course, chinese as 'score' from test2 union 
select name,'数学' as course, math as 'score' from test2 union 
select name,'英语' as course, english as 'score' from test2 union 
select name,'物理' as course, wuli as 'score' from test2 union 
select name,'化学' as course, huaxue as 'score' from test2 order by name asc

-- 第二种写法可以对null值结果集处理
select * from
(select name,'语文' as course, chinese as 'score' from test2 union 
select name,'数学' as course, math as 'score' from test2 union 
select name,'英语' as course, english as 'score' from test2 union 
select name,'物理' as course, wuli as 'score' from test2 union 
select name,'化学' as course, huaxue as 'score' from test2)a
where a.score is not null order by name asc

第一种结果:

有null结果:

没有null结果:

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • mysql中使用instr进行模糊查询方法介绍

    mysql中使用instr进行模糊查询方法介绍

    这篇文章主要介绍了mysql中使用instr进行模糊查询方法介绍,具有一定参考价值,需要的朋友可以了解下。
    2017-10-10
  • MySQL查询随机数据的4种方法和性能对比

    MySQL查询随机数据的4种方法和性能对比

    从MySQL随机选取数据也是我们最常用的一种发发,其最简单的办法就是使用”ORDER BY RAND()”,本文介绍了包括ORDER BY RAND()的4种获取随机数据的方法,并分析了各自的优缺点。
    2014-04-04
  • 详解mysql索引总结----mysql索引类型以及创建

    详解mysql索引总结----mysql索引类型以及创建

    索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。这篇文章主要介绍了详解mysql索引总结----mysql索引类型以及创建,有兴趣的可以了解一下。
    2016-11-11
  • Mysql查询时间区间日期列表实例代码

    Mysql查询时间区间日期列表实例代码

    最近常用到mysql的日期范围搜索,下面这篇文章主要给大家介绍了关于Mysql查询时间区间日期列表的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-04-04
  • linux 下配置安装mysql以及配置【经验】

    linux 下配置安装mysql以及配置【经验】

    这篇文章主要介绍了linux 下配置安装mysql以及配置【经验】,需要的朋友可以参考下
    2016-05-05
  • MySQL关闭过程详解和安全关闭MySQL的方法

    MySQL关闭过程详解和安全关闭MySQL的方法

    这篇文章主要介绍了MySQL关闭过程详解和安全关闭MySQL的方法,在了解了关闭过程后,出现故障能迅速定位,本文还给出了安全关闭MySQL的建议及方法,需要的朋友可以参考下
    2014-08-08
  • MySQL 中 datetime 和 timestamp 的区别与选择

    MySQL 中 datetime 和 timestamp 的区别与选择

    MySQL 中常用的两种时间储存类型分别是datetime和 timestamp。如何在它们之间选择是建表时必要的考虑。下面就谈谈他们的区别和怎么选择,需要的朋友可以参考一下
    2021-09-09
  • Linux mysql命令安装允许远程连接的安装设置方法

    Linux mysql命令安装允许远程连接的安装设置方法

    对大家推荐很好使用的Linux mysql系统,像让大家对Linux mysql系统有所了解,然后对Linux mysql系统全面讲解介绍,希望对大家有用今天特意配置了mysql apache php ,虽然网上很多这方面的例子,但是很多是作者再回忆写的,所以难免有笔误的地方。
    2010-08-08
  • 六条比较有用的MySQL数据库操作的SQL语句小结

    六条比较有用的MySQL数据库操作的SQL语句小结

    本文我们主要介绍了MySQL数据库中的六条比较有用的SQL语句,对于初学者来说,可以直接套用下面的格式即可完成相应的功能,希望本次的介绍能够对您有所帮助。
    2011-08-08
  • 详谈mysqldump数据导出的问题

    详谈mysqldump数据导出的问题

    下面小编就为大家带来一篇详谈mysqldump数据导出的问题。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-03-03

最新评论