行转列

行转列就是把某一个字段的值作为唯一值,然后另外一个字段的行值转换成它的列值。这里依然利用我们系统的学生成绩表作为例子,成绩表记录(行)当中对应着每一个科目的每一个学生的成绩,那我们要做出一个报表是每个学生的所有科目作为一列展示出学生的成绩信息。

首先我们肯定想到的是利用Oracle分组(group by)应该可以实现,实现代码如下:

  1. select c.stuname,
  2. --利用分组聚合函数
  3. sum(decode(b.coursename, '英语(2018上学期)', t.score, 0)) as "英语(2018上学期)",
  4. sum(decode(b.coursename, '数学(2018上学期)', t.score, 0)) as "英语(2018上学期)",
  5. sum(decode(b.coursename, '语文(2018上学期)', t.score, 0)) as "英语(2018上学期)"
  6. from STUDENT.SCORE t, student.course b, student.stuinfo c
  7. where t.courseid = b.courseid
  8. and t.stuid = c.stuid
  9. group by c.stuname

我们利用group by对学生进行分组,然后利用decode对对应的课程的成绩值进行转换,然后再求和即可得到该门成绩的结果值

Oracle11g之后提供了自带函数PIVOT可以完美解决这个行转列的需求

语法:

  1. SELECT * FROM (数据查询集)
  2. PIVOT
  3. (
  4. SUM(Score/*行转列后 列的值*/) FOR
  5. coursename/*需要行转列的列*/ IN (转换后列的值)
  6. )

实例:

  1. select * from (select c.stuname,
  2. b.coursename,
  3. t.score
  4. from STUDENT.SCORE t, student.course b, student.stuinfo c
  5. where t.courseid = b.courseid
  6. and t.stuid = c.stuid ) /*数据源*/
  7. PIVOT
  8. (
  9. SUM(score/*行转列后 列的值*/)
  10. FOR coursename/*需要行转列的列*/ IN ('英语(2018上学期)' as 英语,'数学(2018上学期)' as 数学,'语文(2018上学期)' as 语文 )
  11. ) ;

列转行

Oracle列转行就是把一行当中的列的字段按照行的唯一值转换成多行数据。

利用union all 进行拼接,可以完美的把对应的列转为行记录

  1. select t.stuname, '英语' as coursename ,t.英语 as score from SCORE_COPY t
  2. union all
  3. select t.stuname, '数学' as coursename ,t.数学 as score from SCORE_COPY t
  4. union all
  5. select t.stuname, '语文' as coursename ,t.语文 as score from SCORE_COPY t

利用Oracle自带的列转行函数unpivot也可以完美解决该问题
  1. select 字段 from 数据集
  2. unpivot(自定义列名/*列的值*/ for 自定义列名 in(列名))
  1. select stuname, coursename ,score from
  2. score_copy t
  3. unpivot
  4. (score for coursename in (英语,数学,语文))

执行结果

文档更新时间: 2020-10-20 10:23   作者:张尚