MySQL实现行列转换

吾爱主题 阅读:183 2024-04-02 18:54:54 评论:0

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

13163V403-0.png

图1

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

13163R364-1.png

图2

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

1.行转列的几种方法

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

  1. select uname,uid, -- 正常查询的字段

  2. sum(

  3. case

  4. when course ='英语' then score -- 需要转换的字段

  5. else 0

  6. end) '英语',

  7. sum(

  8. case

  9. when course= '物理' then score

  10. else 0

  11. end) '物理',

  12. sum(

  13. case

  14. when course='化学' then score

  15. else 0

  16. end) '化学'

  17. from course

  18. group by uid

另一种写法:

  1. case course

  2. when '化学' then score

  3. else 0

  4. end

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

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

  1. select uname,uid,

  2. sum(if(`course`='英语',score,0)) '英语',

  3. sumandroid(if(`coursejavascript`='物理',score,0)) '物理',

  4. sum(if(`course`='化学',score,0)) '化学'

  5. from course

  6. group by uname

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

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

13163U2M-2.png

图3

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

13163U9D-3.png

图4

13163Q092-4.png

图5

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

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

  1. select uid,uname,

  2. sum(if(`course`='英语',score,0)) '英语',

  3. sum(if(`course`='物理',score,0)) '物理',

  4. sum(if(`course`='化学',score,0)) '化学',

  5. sum(score) 'total'

  6. from course

  7. group by uname

  8. union

  9. select 'Total',null,

  10. sum(if(`course`='英语',score,0)) '英语',

  11. sum(if(`course`='物理',score,0)) '物理',

  12. sum(if(`course`='化学',score,0)) '化学',

  13. sum(score) 'total'

  14. from course

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

这种方法效果同1.3,

  1. select ifnull(uid,'Total') uid, uname,

  2. http://www.cppcns.comsum(if(`course`='英语',score,0)) '英语',

  3. sum(if(`course`='物理',score,0)) '物理',

  4. sum(if(`course`='化学',score,0)) '化学',

  5. sum(score) 'total'

  6. from course

  7. group by uid

  8. with ROLLUP

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

13163RY3-5.png

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

2.列转行

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

数据库中存储的是这样

13163R364-1 (1).png

图2

而我们需要这样的结果

13163V403-0.png

图1

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

  1. create view rtc as

  2. select ifnull(uid,'Total') uid,uname,

  3. sum(if(`course`='英语',score,0)) '英语',

  4. sum(if(`course`='物理',score,0)) '物理',

  5. sum(if(`course`='化学',score,0)) '化学',

  6. sum(score) js'total'

  7. from course

  8. group by uid

  9. with ROLLUP

  10. -- 下面是列转行代码

  11. select uid,uname,'英语' course,英语 score from rtc where uid <>'Total' and 英语>0

  12. union all select uid,uname,'物理' ,物理 from rtc where uid <>'Total' and 物理>0

  13. union all select uid,uname,'化学' ,化学 from rtc where uid <>'Total' and 化学>0

到此这篇关于MySQL实现行列转换的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://www.cnblogs.com/chenyablog/p/15322573.html

可以去百度分享获取分享代码输入这里。
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

【腾讯云】云服务器产品特惠热卖中
搜索
标签列表
    关注我们

    了解等多精彩内容