MySQL行列转换

摘要:
--普通查询字段sum(casewencourse='English'enscore-要转换为else0end的字段)'English',sum(CASewencouse='chemical'enscoreelse0end')'chemical'from coursegroupbyuid另一种编写方法:sum(如果('course'='English'),直接将sum(分数)'total'添加到上一个查询中。

实际应用中,会遇到需要把表的某些行转换成列,或者把列转换成行的情况。比如一张表在数据库中是这样的:

MySQL行列转换第1张 图1

但是,需要的结果可能是这样:

MySQL行列转换第2张 图2

这个时候就得行列转换了。

1.行转列的几种方法

1.1 case ...  when  ... then ... else ... end

select uname,uid, -- 正常查询的字段
sum(
case
when course ='英语' then score -- 需要转换的字段
else 0
end) '英语',
sum(
case 
when course= '物理' then score
else 0
end) '物理',
sum(
case  
when course='化学' then score
else 0
end) '化学' 
from course
group by uid

另一种写法:

case course 
when '化学' then score
else 0
end

另外若省略‘else 0‘,则没有该课程的同学的分数会填充为null; sum替换成max结果一样。

1.2  if (`字段名1`=‘字段值’,,)

select uname,uid,
sum(if(`course`='英语',score,0)) '英语',
sum(if(`course`='物理',score,0)) '物理',
sum(if(`course`='化学',score,0)) '化学'
from course
group by uname

  

貌似比第一种方法简洁一些,所以下面的扩展是基于这种方法的~

以上两种转换方法结果相同,如图2。另外实际应用中还可能需要有总计的结果,如图3.

MySQL行列转换第3张 图3

total这一列简单,直接在之前的查询基础上加一个sum(score) 'total'即可;Total这一行则可以看成之前的查询不加group by而聚合成一行。因此可以看做是两个表组合到一起如图4和图5:

MySQL行列转换第4张 图4

MySQL行列转换第5张 图5

1.3  if (`字段名1`=‘字段值’,,) + union

把两个查询结果拼接到一起就是图3的样子了,代码如下:

select uid,uname,
sum(if(`course`='英语',score,0)) '英语',
sum(if(`course`='物理',score,0)) '物理',
sum(if(`course`='化学',score,0)) '化学',
sum(score) 'total'
from course
group by uname
union 
select 'Total',null,
sum(if(`course`='英语',score,0)) '英语',
sum(if(`course`='物理',score,0)) '物理',
sum(if(`course`='化学',score,0)) '化学',
sum(score) 'total'
from course

  

1.4  if (`字段名1`=‘字段值’,,) + IFNULL()+with rollup

这种方法效果同1.3,

select ifnull(uid,'Total') uid, uname,
sum(if(`course`='英语',score,0)) '英语',
sum(if(`course`='物理',score,0)) '物理',
sum(if(`course`='化学',score,0)) '化学',
sum(score) 'total'
from course
group by uid
with ROLLUP

  

比1.3简洁一些,效率应该也高一点。with rollup和group by配套使用,会在已有的查询结果上再多出一行,对结果再聚合成一行,即图5的那一行,若不是数字类型,则返回最下面一行的数据,最后一行分组的字段会显示null,因此在配合ifnull()就可以了。

MySQL行列转换第6张

有瑕疵,想把它变成 null,有待完善。

2.列转行

列转行刚好和行转列情况相反,即:

数据库中存储的是这样

MySQL行列转换第2张 图2

而我们需要这样的结果

MySQL行列转换第1张 图1

没有在创建新表,暂且把这个视图当成新表吧

create view rtc as
select ifnull(uid,'Total') uid,uname,
sum(if(`course`='英语',score,0)) '英语',
sum(if(`course`='物理',score,0)) '物理',
sum(if(`course`='化学',score,0)) '化学',
sum(score) 'total'
from course
group by uid
with ROLLUP
-- 下面是列转行代码
select uid,uname,'英语' course,英语 score from rtc where uid <>'Total' and 英语>0
union all select uid,uname,'物理' ,物理 from rtc where uid <>'Total' and 物理>0
union all select uid,uname,'化学' ,化学 from rtc where uid <>'Total' and 化学>0

  

免责声明:文章转载自《MySQL行列转换》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇MySQL会话控制限制登录次数Qt数据库操作下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

python实现websocket

# websocket实现原理 ''' 1.服务端开启socket,监听ip和端口 2.客户端发送连接请求(带上ip和端口) 3.服务端允许连接 4.客户端生成一个随机字符串,和magic string组合进行一个sha1加密,加密。并将随机字符串发送给服务端 5.然后服务端也要用相同的方式进行加密。 6.然后服务端将加密之后的密串返回给客户...

GitLab 后台修改用户密码

GitLab 后台修改用户密码 # 打开控制台 gitlab-rails console production # 找到用户,输入密码,确认密码,保存 user = User.find_by(username: 'zhangsan') user.password = '12345678' user.password_confirmation = '123...

C#.NET Winform承载WCF RESTful API (硬编码配置)

1.新建一个名为“WindowsForms承载WCF”的WINFORM程序。 2.在解决方案里添加一个“WCF 服务库”的项目,名为“WcfYeah”。 3.修改IService1文件,内容如下: using System; using System.Collections.Generic; using System.Linq; using System....

C# Sql 触发器

触发器是一种特殊类型的存储过程,它不同于之前的我们介绍的存储过程。触发器主要是通过事件进行触发被自动调用执行的。而存储过程可以通过存储过程的名称被调用。 Ø 什么是触发器     触发器对表进行插入、更新、删除的时候会自动执行的特殊存储过程。触发器一般用在check约束更加复杂的约束上面。触发器和普通的存储过程的区别是:触发器是当对某一个表进行操作。诸如:...

12.django缓存+图片验证码

1. django缓存设置 django的六种缓存:https://www.cnblogs.com/xiaonq/p/7978402.html#i6 1.1 Django缓存作用 由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显 缓存将一个某个views的返回值保存至内存或者memcache中,5分钟...

[Matlab] 短时傅里叶变换spectrogram函数

Matlab 文档:https://ww2.mathworks.cn/help/signal/ref/spectrogram.html#bultmx7-x 调用:[~,f,t,ps] = spectrogram(data,opt.window,opt.noverlap,freqRange(1):freqRange(2),sample_freq,'reass...