mysql行列转换_MySQL行列转换

本文介绍了MySQL中进行行列转换的方法,包括使用CASE...WHEN...THEN...END、IF()函数以及WITH ROLLUP等实现行转列,并展示了如何将列转换回行。内容详细解释了各种转换技巧及其应用场景。
摘要由CSDN通过智能技术生成

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

88a815a7a73e57c5c4b460bb48c6970d.png 图1

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

4cb1d92d47d5b89407ca797a1dcb2bb6.png 图2

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

1.行转列的几种方法

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

selectuname,uid, -- 正常查询的字段sum(case

when course ='英语' thenscore -- 需要转换的字段

else 0end) '英语',sum(case

when course= '物理' thenscore

else 0end) '物理',sum(case

when course='化学' thenscore

else 0end) '化学'

fromcoursegroup by uid

另一种写法:

casecoursewhen '化学' thenscoreelse 0

end

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

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

selectuname,uid,sum(if(`course`='英语',score,0)) '英语',sum(if(`course`='物理',score,0)) '物理',sum(if(`course`='化学',score,0)) '化学'

fromcoursegroup by uname

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

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

9b76f7cc4a1da8c23d00ab3538ddc152.png 图3

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

7b5b5b10de591273e5e0b9904774295a.png 图4

92b245818b36e85a521b5c378d57fed0.png 图5

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

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

selectuid,uname,sum(if(`course`='英语',score,0)) '英语',sum(if(`course`='物理',score,0)) '物理',sum(if(`course`='化学',score,0)) '化学',sum(score) 'total'

fromcoursegroup byunameunion

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'

fromcoursegroup byuidwith ROLLUP

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

cdcdbacf7844cec7e4fd006383eb0679.png

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

2.列转行

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

数据库中存储的是这样

4cb1d92d47d5b89407ca797a1dcb2bb6.png 图2

而我们需要这样的结果

88a815a7a73e57c5c4b460bb48c6970d.png 图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'

fromcoursegroup byuidwithROLLUP

-- 下面是列转行代码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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值