Oracle 行列转换函数pivot、unpivot的使用(二)

Wesley13
• 阅读 809

一、行转列pivot

关键函数pivot,其用法如下 pivot(聚合函数 for 列名 in(类型))

select * from table_name pivot(max(column_name)                            --行转列后的列的值value,聚合函数是必须要有的
                               for column_name in(value_1,value_2,value_3)     --需要行转列的列及其对应列的属性1/2/3
                                     )

1、首先举一个简单的例子,创建一个数据表

1 create table tmp as select * from (
2 select '张三' student,'语文' course ,78 score from dual union all 
3 select '张三','数学',87 from dual union all 
4 select '张三','英语',82 from dual union all 
5 select '张三','物理',90 from dual union all 
6 select '李四','语文',65 from dual union all 
7 select '李四','数学',77 from dual union all 
8 select '李四','英语',65 from dual union all 
9 select '李四','物理',85 from dual);

Oracle 行列转换函数pivot、unpivot的使用(二)

先使用decode或case when方法

 1 select 
 2   student, 
 3   max(decode(course, '语文', score)) 语文, 
 4   max(decode(course, '数学', score)) 数学, 
 5   max(decode(course, '英语', score)) 英语, 
 6   max(decode(course, '物理', score)) 物理, 
 7   sum(score) total 
 8 from tmp
 9 group by student;
10 -----------------------------------------
11 select 
12   student,
13   max(case when course = '语文' then score end) 语文, 
14   max(case when course = '数学' then score end) 数学, 
15   max(case when course = '英语' then score end) 英语, 
16   max(case when course = '物理' then score end) 物理, 
17   sum(score) total 
18 from tmp
19   group by student;

Oracle 行列转换函数pivot、unpivot的使用(二)

pivot的使用

1 select t.*,  
2   (t.语+t.数+t.外+t.物) as total  
3 from  
4   (select *  
5   from tmp pivot ( max(score) for course in ('语文' as 语 , '数学' as 数, '英语' as 外,'物理' as 物) )  
6   ) t;

结果同上

2、实际开发遇到的问题

有一张目标值表,年、月、日的值都是分开多行显示,现需合并成一行显示,具体数据如下:(type:1-->日,2-->月,3-->年;targetvalue:目标值)

select * from MOVEBI.T_GMS_MBI_TARGET_DATA where targetcode = '31227061'

 Oracle 行列转换函数pivot、unpivot的使用(二)

此数据必须先进性处理,要保证数据可以聚合成一条,若直接使用会出现下列情况:

select * from MOVEBI.T_GMS_MBI_TARGET_DATA pivot(max(targetvalue) for type in (1 day_value,2 mon_value,3 year_value)) where targetcode = '31227061';

Oracle 行列转换函数pivot、unpivot的使用(二)

这不是我们想要的结果,具体改进法法如下:

 1 --方法一:对结果处理
 2 select max(datatime) datatime
 3       ,usercode
 4       ,deptcode
 5       ,deptname
 6       ,targetcode
 7       ,targetname
 8       ,sum(coalesce(day_value,0)) day_value
 9       ,sum(coalesce(mon_value,0)) mon_value
10       ,sum(coalesce(year_value,0)) year_value
11   from(
12 select datatime,usercode,deptcode,deptname,targetcode,targetname,day_value,mon_value,year_value
13   from MOVEBI.T_GMS_MBI_TARGET_DATA
14   pivot(max(targetvalue) for type in (1 day_value,2 mon_value,3 year_value)) where targetcode = '31227061')
15   group by usercode
16           ,deptcode
17           ,deptname
18           ,targetcode
19           ,targetname;
20 --方法二:对原始表处理
21 select *
22   from (select '20181017' datatime,
23                usercode,
24                deptcode,
25                deptname,
26                targetcode,
27                targetname,
28                targetvalue,
29                type
30           from MOVEBI.T_GMS_MBI_TARGET_DATA
31          where datatime in ('20181017', '201810')
32            and targetcode = '31227061') t
33            pivot(max(targetvalue) for type in (1 day_value,2 mon_value,3 year_value)) where targetcode = '31227061';

Oracle 行列转换函数pivot、unpivot的使用(二)

二、列转行unpivot

根据上面的例子创建tmp_2测试用表

Oracle 行列转换函数pivot、unpivot的使用(二)

select student,科目,成绩 from tmp_2 unpivot (成绩 for 科目 in (语文, 数学, 英语, 物理));

Oracle 行列转换函数pivot、unpivot的使用(二)

同样不使用unpivot也可以实现同样的效果,只是sql语句会很长,而且执行速度效率也没有前者高

select student,'语文' 科目, (select 语文 from tmp_2 where student=f.student) 成绩 from tmp_2 f
union
select student,'数学' 科目, (select 数学 from tmp_2 where student=f.student) 成绩 from tmp_2 f
union
select student,'英语' 科目, (select 英语 from tmp_2 where student=f.student) 成绩 from tmp_2 f
union
select student,'物理' 科目, (select 物理 from tmp_2 where student=f.student) 成绩 from tmp_2 f
-------------------------------------------
select student,'语文' 科目,语文 from tmp_2
union
select student,'数学' 科目,语文 from tmp_2
union
select student,'英语' 科目,语文 from tmp_2
union
select student,'物理' 科目,语文 from tmp_2

Oracle 行列转换函数pivot、unpivot的使用(二)

(注:此为学习记录笔记,仅供参考若有问题请指正,后续补充......)

参考文档:https://blog.csdn.net/xiaokui\_wingfly/article/details/42419207

参考文档:https://www.cnblogs.com/harvey888/p/6735093.html

参考文档:https://www.cnblogs.com/markfeifei/p/4009343.html

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
表的纵横表变换
​在我们平时使用数据库时,经常会发现有的表列数过多,为了提高效率,我们经常对要查询的表来纵横表变换。一.行转列1.PIVOT函数PIVOT(任意聚合函数 FOR 列名 IN(类型))    其中,【聚合函数】聚合的字段,是需要转化为列值的字段;【列名】是需要转化为列标识的字段,【类型】即是需要的结果展示,【类型】中可以指定别名; IN中还可以
Stella981 Stella981
3年前
JS 对象数组Array 根据对象object key的值排序sort,很风骚哦
有个js对象数组varary\{id:1,name:"b"},{id:2,name:"b"}\需求是根据name或者id的值来排序,这里有个风骚的函数函数定义:function keysrt(key,desc) {  return function(a,b){    return desc ? ~~(ak
Wesley13 Wesley13
3年前
MySql 相关函数
SELECTGROUP\_CONCAT(column\_name)FROMtable\_namegroupbytable\_name,table\_name2...FIELD()函数自定义排序select\fromuserwheretypein(1,2,3)orderbyFIELD(column,str1,st
Stella981 Stella981
3年前
HIVE 时间操作函数
日期函数UNIX时间戳转日期函数: from\_unixtime语法:   from\_unixtime(bigint unixtime\, string format\)返回值: string说明: 转化UNIX时间戳(从19700101 00:00:00 UTC到指定时间的秒数)到当前时区的时间格式举例:hive   selec
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这