摘 要 对数据库中的数据用SQL实现行列转换,不但需要编写复杂的程序代码,还需要编写存储过程。若引入ORACLE中的分析函数则会使该过程简便很多。首先找出表中所有关键字的属性个数的最大值,设为n,其次为每个关键字新添加n列,并用分析函数查询关键字的属性所处列的位置,然后将每个关键字的多行属性转换成多列属性,最后把生成的多个新列拼成一个串形成一列,从而实现行列转换。
关键字 Oracle数据库;分析函数;行列转换

1 引言

分析函数的设计目的是为了解决诸如“累计计算”等问题。虽然大部分的问题都可以用PL/SQL解决,但是性能并不理想,首先查询本身并不容易编写,其次有些很难在SQL中直接做的查询但实际上是很普通的操作,比如实现数据表中行列传换。这样的问题在SQL中做查询就很困难。在分析函数出现以前,我们必须使用自联查询或者子查询甚至复杂的存储过程实现的语句,现在只要一条简单的SQL语句就可以实现了,而且在执行效率方面也有相当大的提高。本文将以一个实例来描述如何采用分析函数实现数据中的行列互换。

2 原理

2.1 分析函数的格式及语法

分析函数是在一个记录行分组的基础上计算它们的总值。行的分组被称窗口,并通过分析语句定义。对于每记录行,定义了一个“滑动”窗口。该窗口确定“当前行”计算的范围。窗口的大小可由各行的实际编号或由时间等逻辑间隔确定。
分析函数以如下形式开头:
Analytic-Function(,,...)
OVER ()
(1)Analytic-Function:分析函数的名称,Oracle10gR2带的内置分析函数有多个,包括:AVG、CORR、COVAR_POP、COVAR_SAMP、COUNT、LAG、LAST、LEAD、MAX、MIN、RANK、SUM等;对于用户自定义的分析函数,分析函数名称需要满足标识符规则。
(2)Arguments:参数,分析函数通常有0到3个参数,参数可以是任何数字类型或是可以隐式转换为数字类型的数据类型。对于用户自定义的参数,可以根据实际情况使用。
(3)OVER:是分析函数就必须使用的关键字,对于既可作为聚集函数又可作为分析函数的函数,Oracle无法识别,必须用over来标识此函数为分析函数。
(4)Query-Partition-Clause:查询分组子句,根据划分表达式设置的规则,PARTITION BY将一个结果逻辑分成N个分组划分表达式。分析函数独立应用于各个分组,并在应用时重置。
(5)Order-By-Clause:(按…排序分组),是排序子句,根据一个或多个排序表达式对分组进行排序。
(6)Windowing-Clause窗口生成语句:窗口生成语句用以定义滑动或固定数据窗口,分析函数在分组内进行分析。该语句能够对分组中任意定义的滑动或固定窗口进行计算。

2.2 实例原理介绍

本实例是将具有相同关键字的多条记录中的某一不同列合并成一列,例如在一个临时表中包含有用户的编号、电话号码、产品名称、所在营业区以及相关业务名称5个字段,而每个用户的业务可能有多项,这样创建数据表将会造成冗余,现在要想办法将表中编号、电话号码、产品名称、所在营业区四个字段相同的用户的相关业务属性合并成一列解决冗余问题,使用SQL语句会比较困难,甚至需要一定的存储过程。使用Orcale中的分析函数来实现这样的行列转换就比较简单方便了。

3 实例

1)创建临时表
Drop Table temp;
Create Table temp

num varchar2(15 Char),
name varchar2(20 Char),
sex varchar2(2 Char),
classes varchar2(30 Char),
course_name varchar2(50 Char)
);
2)构造数据
insert into temp(num,name,sex,classes,course_name) values ('206211','王艺','男','06-1班','保险学');
insert into temp(num,name,sex,classes,course_name) values ('206212','肖薇','女','06-2','保险学');
insert into temp(num,name,sex,classes,course_name) values ('206212','肖薇','女','06-2','财务管理');
insert into temp(num,name,sex,classes,course_name) values ('206212','肖薇','女','06-2','财务会计');
insert into temp(num,name,sex,classes,course_name) values ('206213','陈雅诗','女','06-2','电子商务');
insert into temp(num,name,sex,classes,course_name) values ('206213','陈雅诗','女','06-2','公共经济学');
insert into temp(num,name,sex,classes,course_name) values ('206213','陈雅诗','女','06-2','公司理财');
insert into temp(num,name,sex,classes,course_name) values ('206213','陈雅诗','女','06-2','管理学原理');
insert into temp(num,name,sex,classes,course_name) values ('206213','陈雅诗','女','06-2','保险学');
insert into temp(num,name,sex,classes,course_name) values ('206214','李丹阳','男','06-1','保险学');
insert into temp(num,name,sex,classes,course_name) values ('206214','李丹阳','男','06-1','财务管理');
insert into temp(num,name,sex,classes,course_name) values ('206214','李丹阳','男','06-1','财务会计');
insert into temp(num,name,sex,classes,course_name) values ('206214','李丹阳','男','06-1','电子商务');
insert into temp(num,name,sex,classes,course_name) values ('206214','李丹阳','男','06-1','公共经济学');
insert into temp(num,name,sex,classes,course_name) values ('206215','杨伊琳','女','06-3班','环境管理学');
insert into temp(num,name,sex,classes,course_name) values ('206215','杨伊琳','女','06-3班','管理学原理');
insert into temp(num,name,sex,classes,course_name) values ('206215','杨伊琳','女','06-3班','商务谈判');
insert into temp(num,name,sex,classes,course_name) values ('206216','李佳琪','男','06-2','土地估计');
Commit;
3)先查一下course_name最多的组合
select max(count(course_name))
from temp
group by num,name,sex,classes;
4) 列的位置
用分析函数中的row_number函数,在num,name,sex,classes相同的情况下course_name所处的列的位置(第几列)。
row_number函数解释:返回有序组中一行的偏移量,从而可用于按特定标准排序的行号。
select num,name,sex,classes,course_name,
row_number() over(partition by num,name,sex,classes order by course_name) rn
from temp;
5)把course_name的所有的行换成列

select num,name,sex,classes,
max(decode(rn,1,course_name,null)) course_name_1,
max(decode(rn,2,course_name,null)) course_name_2,
max(decode(rn,3,course_name,null)) course_name_3,
max(decode(rn,4,course_name,null)) course_name_4,
max(decode(rn,5,course_name,null)) course_name_5
from (select num,name,sex,classes,course_name,
row_number() over(partition by num,name,sex,classes order by course_name) rn
from temp)
group by num,name,sex,classes;
6)把转换后的name拼成一个字符串,放在一行
select num,name,sex,classes,
(max(decode(rn,1,course_name,null)) || max(decode(rn,2,',' || course_name,null)) || max(decode(rn,3,',' || course_name,null)) || max(decode(rn,4,',' || course_name,null)) ||
max(decode(rn,5,',' || course_name,null))) name
from (select num,name,sex,classes,course_name,
row_number() over(partition by num,name,sex,classes order by course_name) rn
from temp)
group by num,name,sex,classes;

4 总结

本文中的程序能够实现以下功能:①计算具有相同关键字的最多的组合;②根据分析函数查询某一关键字所处的列的位置;③把需合并列的所有的行换成列;④把需要合并的某几列拼成一个串。
分析函数除了拥有以上所介绍的功能,还能够实现诸如求和、Top-N查询、统计某个范围的数据行窗口、交叉表查询等功能。
(新疆师范大学 数理信息学院,新疆 830054)

[@more@]

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/658202/viewspace-1036990/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/658202/viewspace-1036990/

用ORACLE分析函数实现行列转换相关推荐

  1. 使用分析函数进行行列转换

    其实使用分析函数进行处理是很好的方式,翻一下Tom的书,将其中的一个例子收录在这里. 比如查询scott.emp表的用户SAL排序信息,可以使用如下查询: SQL> SELECT deptno, ...

  2. oracle数据库,行列转换

    1.所需表的建立与插入数据 无论是在工作中还是在面试中,常常有一类问题经常出现: 依据现有数据,将以行(列)展示的数据转换为以列(行)的形式展示 测试表:SCORE_1/SCORE_2 --建表  插 ...

  3. (转)Oracle中实现行列转换的方法

    (转自)http://blog.csdn.net/Torrice/archive/2006/01/25/587986.aspx 我们在写SQL语句的时候经常需要用到行与列的转换问题,对于一个新手来说可 ...

  4. Oracle 行列转换

    Oracle 行列转换 1.固定列数的行列转换 如 student subject grade --------- ---------- -------- student1 语文 80 student ...

  5. oracle中行列转换总结

    oracle中行列转换 1.行列转换包括以下六种情况: 2. 列转行 2.1 UNION ALL 2.2 MODEL 2.3 COLLECTION 2.4 UNPIVOT 3. 行转列 3.1 AGG ...

  6. Oracle如何实现动态行列转换,Oracle实现行列转换的方法分析

    本文实例讲述了Oracle实现行列转换的方法.分享给大家供大家参考,具体如下: 1.固定列数的行列转换 如: sql;"> student subject grade -------- ...

  7. oracle行列转换总结

    最近论坛很多人提的问题都与行列转换有关系,所以我对行列转换的相关知识做了一个总结, 希望对大家有所帮助,同时有何错疏,恳请大家指出, 我也是在写作过程中学习,算是一起和大家学习吧. 行列转换包括以下六 ...

  8. Oracle行列转换的思考与总结

    最近几天一直在弄Oracle-SQL的问题,涉及到了一些平时没有用到的东西,也因此而在这里郁闷了好久.现在问题得到了解决虽说不算完美.但是还是和大家一起分享一下. 行列转换之一:sum(case wh ...

  9. oracle非常量不能用于privot_Oracle 行列转换函数pivot、unpivot的使用(二)

    一.行转列pivot 关键函数pivot,其用法如下 pivot(聚合函数 for 列名 in(类型)) select * from table_name pivot(max(column_name) ...

最新文章

  1. db2删除大量数据_Python 连接数据库的多种方法
  2. js取小数点后两位数的方法
  3. 2.7万字还原行业面貌,《2019 AI金融风控行业研究报告》正式上线!...
  4. 移植memtester到android平台
  5. 英文书《用unreal来学习c++》_用机器学习来概括《哈利波特》,四句话总结一场戏...
  6. leetcode - 638. 大礼包
  7. JavaScript设计模式(二)-- 工厂方法模式
  8. AspxTreeList获取选中项的值
  9. mysql排序快还是list排序快_2018全国农产品批发市场行业百强排序出炉,快看广西有几个?...
  10. emq 重启_EMQ集群
  11. nginx linux 系统服务,把ngnix注册为linux服务 将Nginx设置为linux下的服务
  12. orientdb java_OrientDB Java连接操作
  13. 服务器1U,2U的含义
  14. 西门子SMART 200 modbus rtu通讯宇电温控器例程
  15. 商业智能BI与业务管理决策思维之三:业务质量分析
  16. IDEA中SVN项目不同颜色含义
  17. 手机计算机怎么玩24点游戏,计算器游戏怎么玩 新手前期玩法介绍
  18. wechat4j开发-菜单创建
  19. 如何更改layui弹出层样式
  20. SD-WAN,让你的组网更灵活

热门文章

  1. python melt函数
  2. 删除文件时显示该文件不在此文件夹中的原因
  3. input 正则控制输入
  4. 【最小生成树】洛谷P2259 Charmer--viv
  5. Uniapp安卓apk原生云端打包完整过程
  6. easyui combotree组件添加搜索功能
  7. 如何将电脑的代理网络以WIFI热点的方式共享
  8. 两服务器文件异地同步,两台群晖之间Moments异地同步方法探索
  9. 直播软件打开测试频道,对比评测:看地方台,这三个直播软件不要错过
  10. 数学基础从高一开始1、集合的概念