用ORACLE分析函数decode实现行列转换
mhr18 2024-09-23 09:40 22 浏览 0 评论
概述
对数据库中的数据用SQL实现行列转换,不但需要编写复杂的程序代码,还需要编写存储过程。若引入ORACLE中的分析函数则会使该过程简便很多。首先找出表中所有关键字的属性个数的最大值,设为n,其次为每个关键字新添加n列,并用分析函数查询关键字的属性所处列的位置,然后将每个关键字的多行属性转换成多列属性,最后把生成的多个新列拼成一个串形成一列,从而实现行列转换。
引言
分析函数的设计目的是为了解决诸如“累计计算”等问题。虽然大部分的问题都可以用PL/SQL解决,但是性能并不理想,首先查询本身并不容易编写,其次有些很难在SQL中直接做的查询但实际上是很普通的操作,比如实现数据表中行列传换。这样的问题在SQL中做查询就很困难。在分析函数出现以前,我们必须使用自联查询或者子查询甚至复杂的存储过程实现的语句,现在只要一条简单的SQL语句就可以实现了,而且在执行效率方面也有相当大的提高。本文将以一个实例来描述如何采用分析函数实现数据中的行列互换。
原理
1、分析函数的格式及语法
分析函数是在一个记录行分组的基础上计算它们的总值。行的分组被称窗口,并通过分析语句定义。对于每记录行,定义了一个“滑动”窗口。该窗口确定“当前行”计算的范围。窗口的大小可由各行的实际编号或由时间等逻辑间隔确定。
分析函数以如下形式开头:
Analytic-Function(<Argument>,<Argument>,...) OVER (<Query-Partition-Clause><Order-By-Clause><Windowing-Clause>)
(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、实例原理介绍
本实例是将具有相同关键字的多条记录中的某一不同列合并成一列,例如在一个临时表中包含有用户的编号、电话号码、产品名称、所在营业区以及相关业务名称5个字段,而每个用户的业务可能有多项,这样创建数据表将会造成冗余,现在要想办法将表中编号、电话号码、产品名称、所在营业区四个字段相同的用户的相关业务属性合并成一列解决冗余问题,使用SQL语句会比较困难,甚至需要一定的存储过程。使用Orcale中的分析函数来实现这样的行列转换就比较简单方便了。
3、实例
1)创建临时表
create table temp ( num varchar2(15), name varchar2(20), sex varchar2(2), classes varchar2(30), course_name varchar2(50) );
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;
总结
本文中的程序能够实现以下功能:
①计算具有相同关键字的最多的组合;
②根据分析函数查询某一关键字所处的列的位置;
③把需合并列的所有的行换成列;
④把需要合并的某几列拼成一个串。
分析函数除了拥有以上所介绍的功能,还能够实现诸如求和、Top-N查询、统计某个范围的数据行窗口、交叉表查询等功能。
后面会分享更多关于sql怎么去优化的内容,感兴趣的朋友可以关注下~·
相关推荐
- 【推荐】一个开源免费、AI 驱动的智能数据管理系统,支持多数据库
-
如果您对源码&技术感兴趣,请点赞+收藏+转发+关注,大家的支持是我分享最大的动力!!!.前言在当今数据驱动的时代,高效、智能地管理数据已成为企业和个人不可或缺的能力。为了满足这一需求,我们推出了这款开...
- Pure Storage推出统一数据管理云平台及新闪存阵列
-
PureStorage公司今日推出企业数据云(EnterpriseDataCloud),称其为组织在混合环境中存储、管理和使用数据方式的全面架构升级。该公司表示,EDC使组织能够在本地、云端和混...
- 对Java学习的10条建议(对java课程的建议)
-
不少Java的初学者一开始都是信心满满准备迎接挑战,但是经过一段时间的学习之后,多少都会碰到各种挫败,以下北风网就总结一些对于初学者非常有用的建议,希望能够给他们解决现实中的问题。Java编程的准备:...
- SQLShift 重大更新:Oracle→PostgreSQL 存储过程转换功能上线!
-
官网:https://sqlshift.cn/6月,SQLShift迎来重大版本更新!作为国内首个支持Oracle->OceanBase存储过程智能转换的工具,SQLShift在过去一...
- JDK21有没有什么稳定、简单又强势的特性?
-
佳未阿里云开发者2025年03月05日08:30浙江阿里妹导读这篇文章主要介绍了Java虚拟线程的发展及其在AJDK中的实现和优化。阅前声明:本文介绍的内容基于AJDK21.0.5[1]以及以上...
- 「松勤软件测试」网站总出现404 bug?总结8个原因,不信解决不了
-
在进行网站测试的时候,有没有碰到过网站崩溃,打不开,出现404错误等各种现象,如果你碰到了,那么恭喜你,你的网站出问题了,是什么原因导致网站出问题呢,根据松勤软件测试的总结如下:01数据库中的表空间不...
- Java面试题及答案最全总结(2025版)
-
大家好,我是Java面试陪考员最近很多小伙伴在忙着找工作,给大家整理了一份非常全面的Java面试题及答案。涉及的内容非常全面,包含:Spring、MySQL、JVM、Redis、Linux、Sprin...
- 数据库日常运维工作内容(数据库日常运维 工作内容)
-
#数据库日常运维工作包括哪些内容?#数据库日常运维工作是一个涵盖多个层面的综合性任务,以下是详细的分类和内容说明:一、数据库运维核心工作监控与告警性能监控:实时监控CPU、内存、I/O、连接数、锁等待...
- 分布式之系统底层原理(上)(底层分布式技术)
-
作者:allanpan,腾讯IEG高级后台工程师导言分布式事务是分布式系统必不可少的组成部分,基本上只要实现一个分布式系统就逃不开对分布式事务的支持。本文从分布式事务这个概念切入,尝试对分布式事务...
- oracle 死锁了怎么办?kill 进程 直接上干货
-
1、查看死锁是否存在selectusername,lockwait,status,machine,programfromv$sessionwheresidin(selectsession...
- SpringBoot 各种分页查询方式详解(全网最全)
-
一、分页查询基础概念与原理1.1什么是分页查询分页查询是指将大量数据分割成多个小块(页)进行展示的技术,它是现代Web应用中必不可少的功能。想象一下你去图书馆找书,如果所有书都堆在一张桌子上,你很难...
- 《战场兄弟》全事件攻略 一般事件合同事件红装及隐藏职业攻略
-
《战场兄弟》全事件攻略,一般事件合同事件红装及隐藏职业攻略。《战场兄弟》事件奖励,事件条件。《战场兄弟》是OverhypeStudios制作发行的一款由xcom和桌游为灵感来源,以中世纪、低魔奇幻为...
- LoadRunner(loadrunner录制不到脚本)
-
一、核心组件与工作流程LoadRunner性能测试工具-并发测试-正版软件下载-使用教程-价格-官方代理商的架构围绕三大核心组件构建,形成完整测试闭环:VirtualUserGenerator(...
- Redis数据类型介绍(redis 数据类型)
-
介绍Redis支持五种数据类型:String(字符串),Hash(哈希),List(列表),Set(集合)及Zset(sortedset:有序集合)。1、字符串类型概述1.1、数据类型Redis支持...
- RMAN备份监控及优化总结(rman备份原理)
-
今天主要介绍一下如何对RMAN备份监控及优化,这里就不讲rman备份的一些原理了,仅供参考。一、监控RMAN备份1、确定备份源与备份设备的最大速度从磁盘读的速度和磁带写的带度、备份的速度不可能超出这两...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- oracle位图索引 (63)
- oracle批量插入数据 (62)
- oracle事务隔离级别 (53)
- oracle 空为0 (50)
- oracle主从同步 (55)
- oracle 乐观锁 (51)
- redis 命令 (78)
- php redis (88)
- redis 存储 (66)
- redis 锁 (69)
- 启动 redis (66)
- redis 时间 (56)
- redis 删除 (67)
- redis内存 (57)
- redis并发 (52)
- redis 主从 (69)
- redis 订阅 (51)
- redis 登录 (54)
- redis 面试 (58)
- 阿里 redis (59)
- redis 搭建 (53)
- redis的缓存 (55)
- lua redis (58)
- redis 连接池 (61)
- redis 限流 (51)