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的源码剖析Innodb buffer的命中率计算

    从MySQL的源码剖析Innodb buffer的命中率计算

    这篇文章主要介绍了从MySQL的源码剖析Innodb buffer的命中率计算,作者结合C语言写的算法来分析innodb buffer hit Ratios,需要的朋友可以参考下
    2015-05-05
  • 在Mysql上创建数据表实例代码

    在Mysql上创建数据表实例代码

    这篇文章主要介绍了如何在Mysql上创建数据表,需要的朋友可以参考下
    2014-03-03
  • MySQL数据的读写分离之maxscale的使用方式

    MySQL数据的读写分离之maxscale的使用方式

    这篇文章主要介绍了MySQL数据的读写分离之maxscale的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • 去掉mysql连接时报警声音的方法

    去掉mysql连接时报警声音的方法

    这篇文章主要介绍了去掉mysql连接时报警声音的方法,本文直接给出设置命令和参数,其中起作用的就是1个-p参数,需要的朋友可以参考下
    2015-01-01
  • MySQL最常问的十道面试题(2023年最新详解版)

    MySQL最常问的十道面试题(2023年最新详解版)

    MySQL是一个关系型数据库管理系统,这是学习Java必学的知识点,也是面试java岗位必考的题目,所以大家要有所重视,这篇文章主要给大家介绍了关于MySQL最常问的十道面试题,是2023年最新详细整理的,需要的朋友可以参考下
    2023-10-10
  • mysql 初始执行文件的使用介绍

    mysql 初始执行文件的使用介绍

    本文将详细介绍mysql 初始执行文件的使用方法,现在晒出来和大家分享下,希望可以帮助你们
    2012-11-11
  • mysql 查询重复的数据的SQL优化方案

    mysql 查询重复的数据的SQL优化方案

    这篇文章主要介绍了mysql 查询重复的数据的SQL优化方案,非常不错的方案推荐给大家。
    2015-02-02
  • 超越MySQL 对流行数据库进行分支的知识小结

    超越MySQL 对流行数据库进行分支的知识小结

    尽管MySQL是最受欢迎的程序之一,但是许多开发人员认为有必要将其拆分成其他项目,并且每个分支项目都有自己的专长。该需求,以及 Oracle 对核心产品增长缓慢的担忧,导致出现了许多开发人员感兴趣的子项目和分支
    2012-01-01
  • MySQL中一条SQL查询语句是如何执行的

    MySQL中一条SQL查询语句是如何执行的

    在写SQL查询语句的时候,通常要考虑SQL语句的查询效率,了解SQL查询语句的执行顺序,可以让我们写出更好的SQL语句,下面这篇文章主要给大家介绍了关于MySQL中一条SQL查询语句是如何执行的相关资料,需要的朋友可以参考下
    2022-04-04
  • innodb_index_stats导入备份数据时报错表主键冲突的解决方法

    innodb_index_stats导入备份数据时报错表主键冲突的解决方法

    下面小编就为大家带来一篇innodb_index_stats导入备份数据时报错表主键冲突的解决方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-03-03

最新评论