问题场景  
  最近在项目中遇到了对每一个类型进行求和并且求该类型所占的比例,当时考虑求出每种类型的和,并在java中分别对每一种类型的和与总和相除求出所占比例。后来,想到这样有点麻烦,并且项目中持久层使用的是iBatis框架,所有考虑从SQL方面进行入手来简化这个问题。

后来SQL的解决方法就为:

SELECT T.CHANNEL AS PATTERN,COUNT(T.TRANSACTIONKEY) AS T_COUNT,SUM(T.AMT) AS T_AMT,ROUND(100 * SUM(T.AMT) / SUM(SUM(T.AMT)) OVER(PARTITION BY 1), 2) AS AMT_PERCENT,ROUND(100 * COUNT(T.TRANSACTIONKEY) / SUM(COUNT(T.TRANSACTIONKEY)) OVER(PARTITION BY 1),2) AS COUNT_PERCENTFROM XX(表名) TWHERE T.PARTY_ID = '100579050'GROUP BY T.CHANNEL 

看到这里自己很佩服SQL的强大,于是刨根问底,深入研究了一番Oracel的OVER(PARTITION BY)函数。

简介
  开窗函数,Oracle从8.1.6开始提供分析函数,分析函数用于计算基于组的某种聚合值,它和聚合函数的不同之处是:对于每个组返回多行,而聚合函数对于每个组只返回一行。

开窗函数指定了分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变化而变化。

下面的测试用例数据语句如下:

 create table T2_TEMP(NAME varchar2(10) primary key,CLASS varchar2(10),SROCE NUMBER )insert into T2_TEMP (NAME, CLASS, SROCE)values ('cfe', '2', 74);insert into T2_TEMP (NAME, CLASS, SROCE)values ('dss', '1', 95);insert into T2_TEMP (NAME, CLASS, SROCE)values ('ffd', '1', 95);insert into T2_TEMP (NAME, CLASS, SROCE)values ('fda', '1', 80);insert into T2_TEMP (NAME, CLASS, SROCE)values ('gds', '2', 92);insert into T2_TEMP (NAME, CLASS, SROCE)values ('gf', '3', 99);insert into T2_TEMP (NAME, CLASS, SROCE)values ('ddd', '3', 99);insert into T2_TEMP (NAME, CLASS, SROCE)values ('adf', '3', 45);insert into T2_TEMP (NAME, CLASS, SROCE)values ('asdf', '3', 55);insert into T2_TEMP (NAME, CLASS, SROCE)values ('3dd', '3', 78); 

View Code
1、over函数的写法:

over(partition by class order by sroce) 按照sroce排序进行累计,order by是个默认的开窗函数,按照class分区。

2、开窗的窗口范围:

over(order by sroce range between 5 preceding and 5 following):窗口范围为当前行数据幅度减5加5后的范围内的。

over(order by sroce rows between 5 preceding and 5 following):窗口范围为当前行前后各移动5行。

3、与over()函数结合的函数的介绍

(1)、查询每个班的第一名的成绩:如下

SELECT * FROM (select t.name,t.class,t.sroce,rank() over(partition by t.class order by t.sroce desc) mm from T2_TEMP t) where mm = 1; 

结果为:

1 得到的结果是:
2 dss        1        95        1
3 ffd        1        95        1
4 gds        2        92        1
5 gf         3        99        1
6 ddd        3        99        1

注意:在求第一名成绩的时候,不能用row_number(),因为如果同班有两个并列第一,row_number()只返回一个结果。

SELECT * FROM (select t.name,t.class,t.sroce,row_number() over(partition by t.class order by t.sroce desc) mm from T2_TEMP t) where mm = 1;

结果为:

dss      1        95        1
gfs      2        92        1
ddd      3        99        1  

可以看出,本来第一名是两个人的并列,结果只显示了一个。

(2)、rank()和dense_rank()可以将所有的都查找出来,rank可以将并列第一名的都查找出来;rank()和dense_rank()区别:rank()是跳跃排序,有两个第二名时接下来就是第四名。

求班级成绩排名:

select t.name,t.class,t.sroce,rank() over(partition by t.class order by t.sroce desc) mm from T2_TEMP t;  

查询结果:

dss        1        95        1
ffd        1        95        1
fda        1        80        3
gds        2        92        1
cfe        2        74        2
gf         3        99        1
ddd        3        99        1
3dd        3        78        3
asdf       3        55        4
adf        3        45        5 

dense_rank()是连续排序,有两个第二名时仍然跟着第三名

select t.name,t.class,t.sroce,dense_rank() over(partition by t.class order by t.sroce desc) mm from T2_TEMP t; 

查询结果:

dss        1        95        1
ffd        1        95        1
fda        1        80        2
gds        2        92        1
cfe        2        74        2
gf         3        99        1
ddd        3        99        1
3dd        3        78        2
asdf       3        55        3
adf        3        45        4 

3、sum()over()的使用

根据班级进行分数求和

select t.name,t.class,t.sroce,sum(t.sroce) over(partition by t.class order by t.sroce desc) mm from T2_TEMP t; 
dss        1        95        190  --由于两个95都是第一名,所以累加时是两个第一名的相加
ffd        1        95        190
fda        1        80        270  --第一名加上第二名的
gds        2        92        92
cfe        2        74        166
gf         3        99        198
ddd        3        99        198
3dd        3        78        276
asdf       3        55        331
adf        3        45        376

4、first_value() over()和last_value() over()的使用

select t.name,t.class,t.sroce,first_value(t.sroce) over(partition by t.class order by t.sroce desc) mm from T2_TEMP t;
select t.name,t.class,t.sroce,last_value(t.sroce) over(partition by t.class order by t.sroce desc) mm from T2_TEMP t; 

分别求出第一个和最后一个成绩。

5、sum() over()的使用

select t.name,t.class,t.sroce,sum(t.sroce) over(partition by t.class order by t.sroce desc) mm from T2_TEMP t; 

求出班级的总分。

下面还有很多用法,就不一一列举了,简单介绍一下,和上面用法类似:
count() over(partition by … order by …):求分组后的总数。
max() over(partition by … order by …):求分组后的最大值。
min() over(partition by … order by …):求分组后的最小值。
avg() over(partition by … order by …):求分组后的平均值。
lag() over(partition by … order by …):取出前n行数据。

lead() over(partition by … order by …):取出后n行数据。

ratio_to_report() over(partition by … order by …):Ratio_to_report() 括号中就是分子,over() 括号中就是分母。

percent_rank() over(partition by … order by …):

6、over partition by与group by的区别:

group by是对检索结果的保留行进行单纯分组,一般和聚合函数一起使用例如max、min、sum、avg、count等一块用。partition by虽然也具有分组功能,但同时也具有其他的高级功能。

OVER(PARTITION BY)函数介绍(oracle数据库)相关推荐

  1. row_number() OVER(PARTITION BY)函数介绍

    OVER(PARTITION BY)函数介绍 开窗函数                Oracle从8.1.6开始提供分析函数,分析函数用于计算基于组的某种聚合值,它和聚合函数的不同之处是:对于每个组 ...

  2. oracle23290,详细介绍Oracle数据库EM Console重建过程

    详细介绍Oracle数据库EM Console重建过程 本文详细介绍了Oracle数据库中EM Console重建的一些知识以及重建时的错误分析与解决,希望能够对您有所帮助. Oracle数据库操作中 ...

  3. Oracle取排序的第五条数据,OVER(PARTITION BY)函数介绍 【oracle中按A分组按B排序,再取B中第一条数据的查询】...

    目录 一.小案例: school表中有①id 序号②class 班级 ③score成绩 三个字段, 使用oracle实现按照班级分区,然后取班级中的第一名. 1.1测试数据如下: --创建学校表sch ...

  4. oracle数据库各组件介绍,Oracle 数据库 组件相关说明【第一部分】

    参考MOS文档: Information On Installed Database Components and Schemas (文档 ID 472937.1) Oracle 组件可以通过下面的S ...

  5. oracle if函数变量,Oracle数据库——PL/SQL编程

    PL/SQL块基本结构 declare -- 声明部分 begin -- 执行部分 exception -- 异常处理部分 end; 声明部分:包含变量.常量定义,由 declare 关键字开始,如果 ...

  6. oracle 数据库 字符串函数

    oracle 数据库 字符串函数 介绍oracle对字符串的操作函数,如图所示,测试字段为:STUDENT 表的 STUNAME 字段 ps:oracle字符串索引从1开始 1.定位索引函数:inst ...

  7. Oracle数据库DECODE函数的使用.

    decode函数是Oracle数据库独有的. 语法为: decode(条件,值1,返回值1,值2,返回值2,...值n,返回值n,缺省值) 例子:select decode(sign(变量1-变量2) ...

  8. oracle REPLACE 函数 介绍

    oracle REPLACE 函数 介绍 oracle REPLACE 函数是用另外一个值来替代串中的某个值. 例如,可以用一个匹配数字来替代字母的每一次出现.REPLACE 的格式如下所示: REP ...

  9. oracle数据库之常用的函数练习

    /*此文章可以作为sql脚本直接运行,某些函数限于oracle数据库! 前面建表和数据插入可以不看,直接看后面红色部分的代码,前面的表只是提供一些数据供大家练习,不用自己再去建表了,真正的内容在后面* ...

最新文章

  1. paramiko 模块封装
  2. MYSQL数据文件--.frm文件(只有.frm文件时的表结构恢复)
  3. 海外应用市场排名前列的VivaVideo All in阿里云
  4. 各类排序算法总结(作者:__Boost)
  5. 无法安装声卡及MODEM驱动
  6. chromebook刷机_如何在Chromebook上拍照
  7. 222. 完全二叉树的节点个数 golang
  8. 基于IDEA的JavaWeb开发环境搭建
  9. MOQL—过滤器(Filter)
  10. myisam 与 innodb的区别,在什么情况下用什么ENGINE
  11. Python-flask中数据库连接池DBUtils
  12. win10以太网未识别的网络的解决方法
  13. 购买的腾讯云服务器一直被ddos恶意攻击怎么解决
  14. 树形结构来了(了解)
  15. win10软件拒绝访问删不掉_win10结束进程时拒绝访问的处理办法
  16. SpringBoot实现动态定时任务
  17. 喜欢猫吗?用这个开源工具撸一只吧!
  18. 成佩涛-项目管理类经理必须了解的工具
  19. “华柔星米”4款折叠屏手机屏幕大起底,买手机容易换屏难?
  20. 怎么将PDF转成Word

热门文章

  1. 【Python报错解决】from PIL import Image 提示调用_imaging失败,已解决
  2. 利用底层键盘钩子拦载任意按键(回调版)
  3. python正负数取余说明
  4. 有关直方图的常用操作
  5. 2.4g和5g要不要合并_路由器WiFi的2.4g和5g要不要合并?
  6. python画苹果标志图片_替换/绘制/分享:让所有 App 拥有 macOS 11 Big Sur 风格的图标...
  7. 获得新成就1024勋章
  8. 今天看了you tu be 上面的舞蹈
  9. sensei鼠标测试软件,「硬核测试:游戏鼠标精准度」赛睿SENSEI 310
  10. 计算机原理论文2000字,计算机原理论文_计算机论文3000字_对计算机的认识论文...