MySQL存储过程中使用动态行转列

2019-01-04 17:00:30刘景俊

为什么要行转列

这是我们进行成绩查询的时候看到的这种纵列的结果,但是一般的时候,我们想要看到下图这种结果

那么需要这样的结果就要进行行转列来操作了。

怎么行转列

像得到上图的结果,一般的行转列,我们只需要这么做

静态行转列

Select st.stuid, st.stunm, MAX(CASE c.coursenm WHEN '大学语文' THEN s.scores ELSE 0 END ) '大学语文', MAX(CASE c.coursenm WHEN '新视野英语' THEN ifnull(s.scores,0) ELSE 0 END ) '新视野英语', MAX(CASE c.coursenm WHEN '离散数学' THEN ifnull(s.scores,0) ELSE 0 END ) '离散数学', MAX(CASE c.coursenm WHEN '概率论与数理统计' THEN ifnull(s.scores,0) ELSE 0 END ) '概率论与数理统计', MAX(CASE c.coursenm WHEN '线性代数' THEN ifnull(s.scores,0) ELSE 0 END ) '线性代数', MAX(CASE c.coursenm WHEN '高等数学(一)' THEN ifnull(s.scores,0) ELSE 0 END ) '高等数学(一)', MAX(CASE c.coursenm WHEN '高等数学(二)' THEN ifnull(s.scores,0) ELSE 0 END ) '高等数学(二)' From Student st Left Join score s On st.stuid = s.stuid Left Join courses c On c.courseno = s.courseno Group by st.stuid

看上面的语句可以看出,我们是在知道固定的几门课程之后,可以使用

MAX(CASE c.coursenm WHEN '线性代数' THEN ifnull(s.scores,0) ELSE 0 END ) '线性代数',

这样的语句来实现行转列

但我们都知道,课程不仅仅这几门,如果用上面的语句去写,第一要确定有多少课程,这么多课程的课程名要再拿出来,那样的话写一个查询语句下来,可是要写很多了。那么就想能不能动态进行行转列的操作?答案当然是肯定的了!

动态行转列

那么如何进行动态行转列呢?

首先我们要动态获取这样的语句

MAX(CASE c.coursenm WHEN '大学语文' THEN s.scores ELSE 0 END ) '大学语文', MAX(CASE c.coursenm WHEN '线性代数' THEN ifnull(s.scores,0) ELSE 0 END ) '线性代数', MAX(CASE c.coursenm WHEN '离散数学' THEN ifnull(s.scores,0) ELSE 0 END ) '离散数学'

而不是像上面那样一句句写出来,那如何得到这样的语句呢?

这里就要用到SQL语句拼接了。具体就是下面的语句

SELECT GROUP_CONCAT(DISTINCT CONCAT( 'MAX(IF(c.coursenm = ''', c.coursenm, ''', s.scores, 0)) AS ''', c.coursenm, '''' ) ) FROM courses c;

得到的结果就是

MAX(IF(c.coursenm = '大学语文', s.scores, 0)) AS '大学语文', MAX(IF(c.coursenm = '新视野英语', s.scores, 0)) AS '新视野英语', MAX(IF(c.coursenm = '离散数学', s.scores, 0)) AS '离散数学', MAX(IF(c.coursenm = '概率论与数理统计', s.scores, 0)) AS '概率论与数理统计', MAX(IF(c.coursenm = '线性代数', s.scores, 0)) AS '线性代数', MAX(IF(c.coursenm = '高等数学(一)', s.scores, 0)) AS '高等数学(一)', MAX(IF(c.coursenm = '高等数学(二)', s.scores, 0)) AS '高等数学(二)'