Oracle 行列转换函数pivot、unpivot的使用(二)
一、行转列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、首先举一个简单的例子,创建一个数据表
create table tmp as select * from (
select '张三' student,'语文' course ,78 score from dual union all
select '张三','数学',87 from dual union all
select '张三','英语',82 from dual union all
select '张三','物理',90 from dual union all
select '李四','语文',65 from dual union all
select '李四','数学',77 from dual union all
select '李四','英语',65 from dual union all
select '李四','物理',85 from dual);

先使用decode或case when方法
select
student,
max(decode(course, '语文', score)) 语文,
max(decode(course, '数学', score)) 数学,
max(decode(course, '英语', score)) 英语,
max(decode(course, '物理', score)) 物理,
sum(score) total
from tmp
group by student;
-----------------------------------------
select
student,
max(case when course = '语文' then score end) 语文,
max(case when course = '数学' then score end) 数学,
max(case when course = '英语' then score end) 英语,
max(case when course = '物理' then score end) 物理,
sum(score) total
from tmp
group by student;

pivot的使用
select t.*,
(t.语+t.数+t.外+t.物) as total
from
(select *
from tmp pivot ( max(score) for course in ('语文' as 语 , '数学' as 数, '英语' as 外,'物理' as 物) )
) t;
结果同上
2、实际开发遇到的问题
有一张目标值表,年、月、日的值都是分开多行显示,现需合并成一行显示,具体数据如下:(type:1-->日,2-->月,3-->年;targetvalue:目标值)
select * from MOVEBI.T_GMS_MBI_TARGET_DATA where targetcode = '31227061'

此数据必须先进性处理,要保证数据可以聚合成一条,若直接使用会出现下列情况:
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 = '';

这不是我们想要的结果,具体改进法法如下:
--方法一:对结果处理
select max(datatime) datatime
,usercode
,deptcode
,deptname
,targetcode
,targetname
,sum(coalesce(day_value,0)) day_value
,sum(coalesce(mon_value,0)) mon_value
,sum(coalesce(year_value,0)) year_value
from(
select datatime,usercode,deptcode,deptname,targetcode,targetname,day_value,mon_value,year_value
from MOVEBI.T_GMS_MBI_TARGET_DATA
pivot(max(targetvalue) for type in (1 day_value,2 mon_value,3 year_value)) where targetcode = '')
group by usercode
,deptcode
,deptname
,targetcode
,targetname;
--方法二:对原始表处理
select *
from (select '' datatime,
usercode,
deptcode,
deptname,
targetcode,
targetname,
targetvalue,
type
from MOVEBI.T_GMS_MBI_TARGET_DATA
where datatime in ('', '')
and targetcode = '') t
pivot(max(targetvalue) for type in (1 day_value,2 mon_value,3 year_value)) where targetcode = '';

二、列转行unpivot
根据上面的例子创建tmp_2测试用表

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

同样不使用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

(注:此为学习记录笔记,仅供参考若有问题请指正,后续补充......)
参考文档: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
Oracle 行列转换函数pivot、unpivot的使用(二)的更多相关文章
- oracle行列转换函数的使用
oracle 10g wmsys.wm_concat行列转换函数的使用: 首先让我们来看看这个神奇的函数wm_concat(列名),该函数可以把列值以","号分隔起来,并显示成一行 ...
- Oracle11g 行列转换函数PIVOT and UNPIVOT
作为Oracle开发工程师,推荐大伙看看 PIVOT and UNPIVOT Operators in Oracle Database 11g Release 1 This article shows ...
- oracle 行列转换函数之WM_CONCAT和LISTAGG的使用(一)
一.wm_concat函数 wm_concat能够实现同样的功能,但是有时在11g中使用需要用to_char()进行转换,否则会出现不兼容现象(WMSYS.WM_CONCAT: 依赖WMSYS 用户, ...
- Oracle行列转换
一.建表与插入数据 1.1.建表 create table kecheng ( id NUMBER, name ), course ), score NUMBER ); insert into kec ...
- oracle 行列转换
oracle 行列转换列名如果是数字,用双引号包住 如下: -- 建表 create table workinfo(wid integer primary key,sid integer ,CON ...
- Oracle 大小写转换函数
Oracle 大小写转换函数 转大写UPPER 转小写LOWER 测试: select UPPER('Test') as u from dual; select LOWER('Test') as l ...
- SQL(横表和纵表)行列转换,PIVOT与UNPIVOT的区别和使用方法举例,合并列的例子
使用过SQL Server 2000的人都知道,要想实现行列转换,必须综合利用聚合函数和动态SQL,具体实现起来需要一定的技巧,而在SQL Server 2005中,使用新引进的关键字PIVOT/UN ...
- 行列转换小结 Pivot ,Unpivot (转,改)
行专列 Pivot 1)SQL 2000版本 静态 SELECT ID , SUM(CASE Code WHEN 'Item1' THEN Value END) AS Item1 , SUM(CASE ...
- KingbaseES 行列转换函数
关键字: 行专列,列转行, pivot, unpivot 行列转换是在数据分析中经常用到的一项功能,KingbaseES从V8R6C3B0071版本开始通过扩展插件(kdb_utils_func ...
随机推荐
- idea hibernate jpa 生成实体类
0,添加mysql数据库连接 1,生成个hibernate.cfg.xml 2,打开Persisitence 3,Import Databases Schema 4,选择表生成实体类
- SimpleDateFormat是线程不安全的
线程不安全的SimpleDateFormat SimpleDateFormat是线程不安全的 SimpleDateFormat是Java提供的一个格式化和解析日期的工具类,日常开发中应该经常会用到,但 ...
- Redis与Java的链接Jedis(二)
就像jdbc跟java链接数据库一样 redis跟java链接最好的工具就是Jedis 相关资源下载:https://github.com/xetorthio/jedis 正常建立java项目, 导入 ...
- PrintWriter类
PrintWriter是一种过滤流,也是一种处理流,即能对字节流和字符流进行处理. 1.查询API后,我们发现,会有八种构造方法.即: PrintWriter(File file) Creates a ...
- Linux系统优化及状态监控
1.查看系统进程命令 top 进入后可按s 加时间,指定多长时间刷新一次 2.查看cpu信息 cat /proc/cpuinfo 3.查看内存信息 cat /proc/meminfo 4.清理内存:主 ...
- imagelist用法
1.添加一个Imagelist控件,并双击控件图标如下图 2.点击新增按钮
- async异步操作和同步上下文
第8章 哪个线程运行我的代码 看到社区里的朋友没有翻译完这本书,我接着对一下的章节进行翻译 像我之前说的,异步编程就是关于线程的.那就意味着我们需要理解在C#程序中哪个.NET线程什么时候运行我们的代 ...
- c# 与 Mysql 的通讯方式总结
两种开发方式 1.使用 vs 自带的可视化工具,不推荐. 在 vs 的项目中添加 ‘数据集’,然后通过可视化的工具添加数据库为数据源,默认可添加 SQL Server 和 Oracle 等,添加 My ...
- 跨DLL操作fopen的返回值导致出错
在设置成/MD或/MDd不会导致出错 设置成/MT或/MTd的情况下会导致出错 看了CRT的实现,估计是因为fopen创建了CriticalSection来保护文件,但是在/MT的情况下,一个DLL里 ...
- maven-compiler-plugin 版本错误解决方法
项目执行Maven build后出现WARNING提示.报如信息如下,根据报错信息猜测是maven-compiler-plugin的版本信息问题 [WARNING] [WARNING] Some pr ...