Mysql 行列转换查询 时间: 2018-03-30 15:12 分类: mysql,数据库 ####前言 不得不说,自己在数据库这一块还是比较薄弱,还只停留在简单的增删改查上面。所以每次在做数据库笔试题时总是头皮发麻,笔试不同于机试,无法在线调试 sql 语句,就算写出来了也不知道是否正确。昨天面试时笔试题数据库题目占分较大,而自己又恰好写不出来,以至于表现不是很好,所以吃一堑长一智,每面一次都要好好反省一下自身的不足。 ####Mysql 数据表行转列 这是昨天面试笔试上的一道题,有如下一张表 A: | 月份 | 部门 | 业绩 | | ------------ | ------------ | ------------ | | 一月份 | A | 10 | | 一月份 | B | 8 | | 一月份 | C | 5 | | 二月份 | A | 8 | | 二月份 | B | 9 | | 二月份 | C | 11 | | 三月份 | A | 12 | | 三月份 | B | 7 | | 三月份 | C | 10 | 要求将其变换为如下结果: | 部门 | 一月份 | 二月份 | 三月份 | | ------------ | ------------ | ------------ | ------------ | | A | 12 | 8 | 12 | | B | 9 | 9 | 7 | | C | 11 | 11 | 10 | 这种查询在报表查询中非常常见的,对比上面两种表结构,显然第一种更符合数据库设计,第二种更符合用户观看,所以此类数据库行到列的转换还是很有必要的。 下面是[znotes](http://znotes.in "znotes")大神教我的方法: ```mysql SELECT dpt_name '部门', SUM(CASE WHEN mon='一月份' THEN yeji END) AS '一月份', SUM(CASE mon WHEN '二月份' THEN yeji END) AS '二月份', SUM(CASE mon WHEN '三月份' THEN yeji END) AS '三月份' FROM tb_a GROUP BY dpt_name; ``` 查询结果如下: ![table1.jpg](https://0o0.me/usr/uploads/2018/03/1843221745.jpg) 查询成功,正确的进行了行到列的转换。 后来在翻阅Mysql书上关于`CASE`函数的时候,虽然上面没有说能够用来做行到列的转换查询,但是却看到了与之相邻页面的`IF`语句,`CASE`、`IF`不禁想到`JAVA`中的 if 和 switch case,所以猜测 Mysql 中的 `CASE`与`IF`是否也有着异曲同工之妙呢,于是大胆尝试以下 sql 语句: ```mysql SELECT dpt_name '部门', SUM(IF(mon='一月份', yeji, 0)) AS '一月份', SUM(IF(mon='二月份', yeji, 0)) AS '二月份', SUM(IF(mon='三月份', yeji, 0)) AS '三月份' FROM tb_a GROUP BY dpt_name; ``` 完美运行,得到正确结果。 网上关于行到列的转换大多都是用的`CASE WHEN`,可以说是千变一律了,不知是否有人和我一样做过上面大胆地猜测与尝试呢。看来,在学习的过程中学以用之固然重要,但更重要的是学以思之啊。 ####Mysql 数据表列转行 还是上面的表,执行如下语句: ```mysql select mon '月份', group_concat(dpt_name, '业绩:', yeji) from tb_a group by mon; ``` 将得到如下结果: ![table2.jpg](https://0o0.me/usr/uploads/2018/03/2734402947.jpg) 关键字`Group_CONCAT`,作用是将分组结果中的每一条数据进行拼接。 ####总结 sql 语句真是博大精深啊,革命尚未成功,同志仍需努力! 标签: mysql