设为首页 收藏本站
查看: 983|回复: 0

[经验分享] Oracle开发专题之:分析函数(OVER)

[复制链接]

尚未签到

发表于 2016-7-24 12:37:14 | 显示全部楼层 |阅读模式
目录:
===============================================
1.Oracle分析函数简介
2. Oracle分析函数简单实例
3.分析函数OVER解析

一、Oracle分析函数简介:

在日常的生产环境中,我们接触得比较多的是OLTP系统(即Online Transaction Process),这些系统的特点是具备实时要求,或者至少说对响应的时间多长有一定的要求;其次这些系统的业务逻辑一般比较复杂,可能需要经过多次的运算。比如我们经常接触到的电子商城。

在这些系统之外,还有一种称之为OLAP的系统(即Online Aanalyse Process),这些系统一般用于系统决策使用。通常和数据仓库、数据分析、数据挖掘等概念联系在一起。这些系统的特点是数据量大,对实时响应的要求不高或者根本不关注这方面的要求,以查询、统计操作为主。

我们来看看下面的几个典型例子:
①查找上一年度各个销售区域排名前10的员工
②按区域查找上一年度订单总额占区域订单总额20%以上的客户
③查找上一年度销售最差的部门所在的区域
④查找上一年度销售最好和最差的产品

我们看看上面的几个例子就可以感觉到这几个查询和我们日常遇到的查询有些不同,具体有:

①需要对同样的数据进行不同级别的聚合操作
②需要在表内将多条数据和同一条数据进行多次的比较
③需要在排序完的结果集上进行额外的过滤操作

二、Oracle分析函数简单实例:

下面我们通过一个实际的例子:按区域查找上一年度订单总额占区域订单总额20%以上的客户,来看看分析函数的应用。

【1】测试环境:

DSC0000.gif SQL>descorders_tmp;
Name
Null?Type
-----------------------------------------------
CUST_NBRNOTNULLNUMBER(5)
REGION_ID
NOTNULLNUMBER(5)
SALESPERSON_ID
NOTNULLNUMBER(5)
YEARNOTNULLNUMBER(4)
MONTHNOTNULLNUMBER(2)
TOT_ORDERS
NOTNULLNUMBER(7)
TOT_SALES
NOTNULLNUMBER(11,2)

【2】测试数据:
SQL>select*fromorders_tmp;

CUST_NBRREGION_IDSALESPERSON_ID
YEARMONTHTOT_ORDERSTOT_SALES
--------------------------------------------------------------------------
1171120017212204
454200110237802
7672001233750
106820011221691
106720012342624
1571220005624
127920006250658
15220003244494
15120009274864
25420003235060
2542000446454
251200010435580
454200012239190

13rowsselected.

【3】测试语句:
SQL>selecto.cust_nbrcustomer,
2o.region_idregion,
3sum(o.tot_sales)cust_sales,
4sum(sum(o.tot_sales))over(partitionbyo.region_id)region_sales
5fromorders_tmpo
6whereo.year=2001
7groupbyo.region_id,o.cust_nbr;

CUSTOMERREGIONCUST_SALESREGION_SALES
------------------------------------------
453780237802
76375068065
1066431568065
1171220412204


三、分析函数OVER解析:

请注意上面的绿色高亮部分,group by的意图很明显:将数据按区域ID,客户进行分组,那么Over这一部分有什么用呢?假如我们只需要统计每个区域每个客户的订单总额,那么我们只需要group by o.region_id,o.cust_nbr就够了。但我们还想在每一行显示该客户所在区域的订单总额,这一点和前面的不同:需要在前面分组的基础上按区域累加。很显然group by和sum是无法做到这一点的(因为聚集操作的级别不一样,前者是对一个客户,后者是对一批客户)。

这就是over函数的作用了!它的作用是告诉SQL引擎:按区域对数据进行分区,然后累积每个区域每个客户的订单总额(sum(sum(o.tot_sales)))。

现在我们已经知道2001年度每个客户及其对应区域的订单总额,那么下面就是筛选那些个人订单总额占到区域订单总额20%以上的大客户了
SQL>select*
2from(selecto.cust_nbrcustomer,
3o.region_idregion,
4sum(o.tot_sales)cust_sales,
5sum(sum(o.tot_sales))over(partitionbyo.region_id)region_sales
6fromorders_tmpo
7whereo.year=2001
8groupbyo.region_id,o.cust_nbr)all_sales
9whereall_sales.cust_sales>all_sales.region_sales*0.2;

CUSTOMERREGIONCUST_SALESREGION_SALES
------------------------------------------
453780237802
1066431568065
1171220412204

SQL
>

现在我们已经知道这些大客户是谁了!哦,不过这还不够,如果我们想要知道每个大客户所占的订单比例呢?看看下面的SQL语句,只需要一个简单的Round函数就搞定了。SQL>selectall_sales.*,
2100*round(cust_sales/region_sales,2)||'%'Percent
3from(selecto.cust_nbrcustomer,
4o.region_idregion,
5sum(o.tot_sales)cust_sales,
6sum(sum(o.tot_sales))over(partitionbyo.region_id)region_sales
7fromorders_tmpo
8whereo.year=2001
9groupbyo.region_id,o.cust_nbr)all_sales
10whereall_sales.cust_sales>all_sales.region_sales*0.2;

CUSTOMERREGIONCUST_SALESREGION_SALES
PERCENT
----------------------------------------------------------------------------------
453780237802100%
106643156806594%
1171220412204100%

SQL
>

总结:

①Over函数指明在那些字段上做分析,其内跟Partition by表示对数据进行分组。注意Partition by可以有多个字段。

②Over函数可以和其它聚集函数、分析函数搭配,起到不同的作用。例如这里的SUM,还有诸如Rank,Dense_rank等。

参考资料:《Mastering Oracle SQL》(ByAlanBeaulieu, SanjayMishraO'Reilly June 20040-596-00632-2)


-------------------------------------------------------------
生活就像打牌,不是要抓一手好牌,而是要尽力打好一手烂牌。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-248648-1-1.html 上篇帖子: Oracle 创建索引的基本规则总结 下篇帖子: Oracle中 ROWNUM 的使用心得
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表