MySQL行转列操作

所谓的行转列操作,就是将一个表的行信息转化为列信息,说着可能比较笼统,这里先举个例子,如下:

+----+-----------+--------+-------+| ID | USER_NAME | COURSE | SCORE |+----+-----------+--------+-------+|  | 张三   | 数学  |   ||  | 张三   | 语文  |   ||  | 张三   | 英语  |   ||  | 李四   | 数学  |   ||  | 李四   | 语文  |   ||  | 李四   | 英语  |   ||  | 王五   | 数学  |   ||  | 王五   | 语文  |   ||  | 王五   | 英语  |   |+----+-----------+--------+-------+ rows in set (0.00 sec)+-----------+--------+--------+--------+| user_name | 数学  | 语文  | 英语  |+-----------+--------+--------+--------+| 张三   |   |   |   || 李四   |   |   |   || 王五   |   |   |   |+-----------+--------+--------+--------+ rows in set (0.00 sec)

1 case when操作方法

要实现上面的功能,我们需要进行分析,首先,我们需要生成三个列,分别是数学,语文和英语,然后给每个列中的值填入对应的数据。这里需要用到mysql的case when then end操作,也就是条件操作,关于这个条件语句,首先我们给出解释:

case colume   when condition1 then result1  when condition2 then result2  when condition3 then result3else result4end

现在开始试验:

首先我们创建一张表,并插入如下数据:

mysql-yeyz ::>>select * from test_tbl;+----+-----------+--------+-------+| ID | USER_NAME | COURSE | SCORE |+----+-----------+--------+-------+|  | 张三   | 数学  |   ||  | 张三   | 语文  |   ||  | 张三   | 英语  |   ||  | 李四   | 数学  |   ||  | 李四   | 语文  |   ||  | 李四   | 英语  |   ||  | 王五   | 数学  |   ||  | 王五   | 语文  |   ||  | 王五   | 英语  |   |+----+-----------+--------+-------+ rows in set (0.00 sec)
mysql-yeyz ::>>SELECT user_name ,(CASE course WHEN '数学' THEN score ELSE END ) 数学 FROM test_tbl;+-----------+--------+| user_name | 数学  |+-----------+--------+| 张三   |   || 张三   |    || 张三   |    || 李四   |   || 李四   |    || 李四   |    || 王五   |   || 王五   |    || 王五   |    |+-----------+--------+ rows in set (0.00 sec)
mysql-yeyz ::>>SELECT user_name ,  ->   (CASE course WHEN '数学' THEN score ELSE END ) 数学,  ->   (CASE course WHEN '语文' THEN score ELSE END ) 语文,  ->   (CASE course WHEN '英语' THEN score ELSE END ) 英语  -> FROM test_tbl;+-----------+--------+--------+--------+| user_name | 数学  | 语文  | 英语  |+-----------+--------+--------+--------+| 张三   |   |    |    || 张三   |    |   |    || 张三   |    |    |   || 李四   |   |    |    || 李四   |    |   |    || 李四   |    |    |   || 王五   |   |    |    || 王五   |    |   |    || 王五   |    |    |   |+-----------+--------+--------+--------+ rows in set (0.00 sec)
+-----------+--------+--------+--------+| user_name | 数学  | 语文  | 英语  |+-----------+--------+--------+--------+| 张三   |   |   |   || 李四   |   |   |   || 王五   |   |   |   |+-----------+--------+--------+--------+

下面我们给出最终结果:

mysql-yeyz 13:55:52>>SELECT user_name ,  ->   MAX(CASE course WHEN '数学' THEN score ELSE END ) 数学,  ->   MAX(CASE course WHEN '语文' THEN score ELSE END ) 语文,  ->   MAX(CASE course WHEN '英语' THEN score ELSE END ) 英语  -> FROM test_tbl  -> GROUP BY USER_NAME;+-----------+--------+--------+--------+| user_name | 数学  | 语文  | 英语  |+-----------+--------+--------+--------+| 张三   |   34 |   58 |   58 || 李四   |   45 |   87 |   45 || 王五   |   76 |   34 |   89 |+-----------+--------+--------+--------+3 rows in set (0.00 sec)mysql-yeyz ::>>SELECT user_name ,  ->   sum(CASE course WHEN '数学' THEN score ELSE END ) 数学,  ->   sum(CASE course WHEN '语文' THEN score ELSE END ) 语文,  ->   sum(CASE course WHEN '英语' THEN score ELSE END ) 英语  -> FROM test_tbl  -> GROUP BY USER_NAME;+-----------+--------+--------+--------+| user_name | 数学  | 语文  | 英语  |+-----------+--------+--------+--------+| 张三   |   34 |   58 |   58 || 李四   |   45 |   87 |   45 || 王五   |   76 |   34 |   89 |+-----------+--------+--------+--------+3 rows in set (0.00 sec)mysql-yeyz ::>>SELECT user_name ,  ->   MIN(CASE course WHEN '数学' THEN score ELSE END ) 数学,  ->   MIN(CASE course WHEN '语文' THEN score ELSE END ) 语文,  ->   MIN(CASE course WHEN '英语' THEN score ELSE END ) 英语  -> FROM test_tbl  -> GROUP BY USER_NAME;+-----------+--------+--------+--------+| user_name | 数学  | 语文  | 英语  |+-----------+--------+--------+--------+| 张三   |   0 |   0 |   0 || 李四   |   0 |   0 |   0 || 王五   |   0 |   0 |   0 |+-----------+--------+--------+--------+3 rows in set (0.00 sec)

2 if操作方法

上面的case when操作方法理解了,那么if的操作方法也很好理解,原理是一样的,只不过是把case when的语法转换为if方式,如下

mysql-yeyz 14:12:42>>SELECT user_name ,  ->   MAX(if (course= '数学',score,) ) 数学,  ->   MAX(if (course= '语文',score,) ) 语文,  ->   MAX(if (course= '英语',score,) ) 英语  -> FROM test_tbl  -> GROUP BY USER_NAME;+-----------+--------+--------+--------+| user_name | 数学  | 语文  | 英语  |+-----------+--------+--------+--------+| 张三   |   34 |   58 |   58 || 李四   |   45 |   87 |   45 || 王五   |   76 |   34 |   89 |+-----------+--------+--------+--------+3 rows in set (0.00 sec)

当我们把基本的行转列实现之后,我们现在需要在转换之后的表上面添加一个total字段,这个字段的添加我们可以通过下面的方法,即在最开始统计的时候,就把score值也统计进去,如下:

mysql-yeyz 14:18:06>>SELECT user_name ,  ->   (CASE course WHEN '数学' THEN score ELSE END ) 数学,  ->   (CASE course WHEN '语文' THEN score ELSE END ) 语文,  ->   (CASE course WHEN '英语' THEN score ELSE END ) 英语,  -> (score) total  -> FROM test_tbl;+-----------+--------+--------+--------+-------+| user_name | 数学  | 语文  | 英语  | total |+-----------+--------+--------+--------+-------+| 张三   |   34 |   0 |   0 |  34 || 张三   |   0 |   58 |   0 |  58 || 张三   |   0 |   0 |   58 |  58 || 李四   |   45 |   0 |   0 |  45 || 李四   |   0 |   87 |   0 |  87 || 李四   |   0 |   0 |   45 |  45 || 王五   |   76 |   0 |   0 |  76 || 王五   |   0 |   34 |   0 |  34 || 王五   |   0 |   0 |   89 |  89 |+-----------+--------+--------+--------+-------+9 rows in set (0.00 sec)
mysql-yeyz 14:18:29>>SELECT user_name ,  ->   sum(CASE course WHEN '数学' THEN score ELSE END ) 数学,  ->   sum(CASE course WHEN '语文' THEN score ELSE END ) 语文,  ->   sum(CASE course WHEN '英语' THEN score ELSE END ) 英语,  -> sum(score) total  -> FROM test_tbl  -> GROUP BY USER_NAME;+-----------+--------+--------+--------+-------+| user_name | 数学  | 语文  | 英语  | total |+-----------+--------+--------+--------+-------+| 张三   |   34 |   58 |   58 |  150 || 李四   |   45 |   87 |   45 |  177 || 王五   |   76 |   34 |   89 |  199 |+-----------+--------+--------+--------+-------+3 rows in set (0.00 sec)

如果我们对于结果的显示格式要求不是那么细致的话,也可以用一种粗犷的方法,就是group_concat函数,将所有的列都写在一起,用一个字段表示,效果如下:

mysql-yeyz 14:19:13>>SELECT user_name,GROUP_CONCAT(`course`,":",score)AS 成绩 FROM test_tbl GROUP BY user_name;+-----------+-------------------------------+| user_name | 成绩             |+-----------+-------------------------------+| 张三   | 数学:34,语文:58,英语:58    || 李四   | 数学:45,语文:87,英语:45    || 王五   | 数学:76,语文:34,英语:89    |+-----------+-------------------------------+3 rows in set (0.00 sec)

更多相关文章

  1. ES6 变量声明,箭头函数,数组方法,解构赋值,JSON,类与继承,模块化练习
  2. 浅谈Java中Collections.sort对List排序的两种方法
  3. Python list sort方法的具体使用
  4. python list.sort()根据多个关键字排序的方法实现
  5. android上一些方法的区别和用法的注意事项
  6. android实现字体闪烁动画的方法
  7. Android中dispatchDraw分析
  8. Android四大基本组件介绍与生命周期
  9. Android(安卓)MediaPlayer 常用方法介绍

随机推荐

  1. JSP 或HTML 如何通过button按钮转到想去
  2. 两个堆叠的元素与他们旁边的元素成比例增
  3. 如何将标记中的值传递给PHP变量?
  4. HTML语言中img标签的alt属性和title属性
  5. 使用 html5 svg 绘制图形
  6. XSL:包括根本不工作
  7. 在不可见的webbrowser对象中模拟按键C#
  8. jquery将html转换为字符串和html
  9. img在div中不按百分比调整大小
  10. 为什么代码放到DW里运行,和用记事保存为H