OVER(PARTITION BY)函数介绍

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

开窗函数指定了分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变化而变化,举例如下:
1:over后的写法:    
   over(order by salary) 按照salary排序进行累计,order by是个默认的开窗函数
   over(partition by deptno)按照部门分区

   over(partition by deptno order by salary)

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

举例:

--sum(s)over(order by s range between 2 preceding and 2 following) 表示加2或2的范围内的求和

select name,class,s, sum(s)over(order by s range between 2 preceding and 2 following) mm from t2
adf        3        45        45  --45加2减2即43到47,但是s在这个范围内只有45
asdf       3        55        55
cfe        2        74        74
3dd        3        78        158 --78在76到80范围内有78,80,求和得158
fda        1        80        158
gds        2        92        92
ffd        1        95        190
dss        1        95        190
ddd        3        99        198

gf         3        99        198

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

举例:

--sum(s)over(order by s rows between 2 preceding and 2 following)表示在上下两行之间的范围内
select name,class,s, sum(s)over(order by s rows between 2 preceding and 2 following) mm from t2
adf        3        45        174  (45+55+74=174)
asdf       3        55        252   (45+55+74+78=252)
cfe        2        74        332    (74+55+45+78+80=332)
3dd        3        78        379    (78+74+55+80+92=379)
fda        1        80        419
gds        2        92        440
ffd        1        95        461
dss        1        95        480
ddd        3        99        388
gf         3        99        293
over(order by salary range between unbounded preceding and unbounded following)或者

over(order by salary rows between unbounded preceding and unbounded following):窗口不做限制

3、与over函数结合的几个函数介绍

row_number()over()、rank()over()和dense_rank()over()函数的使用

下面以班级成绩表t2来说明其应用

t2表信息如下:
cfe        2        74
dss        1        95
ffd        1        95
fda        1        80
gds        2        92
gf         3        99
ddd        3        99
adf        3        45
asdf       3        55
3dd        3        78

select * from                                                                      
    (                                                                           
    select name,class,s,rank()over(partition by class order by s desc) mm from t2
    )                                                                           
    where mm=1;
得到的结果是:
dss        1        95        1
ffd        1        95        1
gds        2        92        1
gf         3        99        1
ddd        3        99        1

注意:
    1.在求第一名成绩的时候,不能用row_number(),因为如果同班有两个并列第一,row_number()只返回一个结果;
select * from                                                                      
    (                                                                           
    select name,class,s,row_number()over(partition by class order by s desc) mm from t2
    )                                                                           
    where mm=1;
1        95        1  --95有两名但是只显示一个
2        92        1
3        99        1 --99有两名但也只显示一个

2.rank()和dense_rank()可以将所有的都查找出来:
如上可以看到采用rank可以将并列第一名的都查找出来;
     rank()和dense_rank()区别:
     --rank()是跳跃排序,有两个第二名时接下来就是第四名;
select name,class,s,rank()over(partition by class order by s desc) mm from t2
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()l是连续排序,有两个第二名时仍然跟着第三名
select name,class,s,dense_rank()over(partition by class order by s desc) mm from t2
dss        1        95        1
ffd        1        95        1
fda        1        80        2 --连续排序(仍为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

--sum()over()的使用
select name,class,s, sum(s)over(partition by class order by s desc) mm from t2 --根据班级进行分数求和
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

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

--找出这三条电路每条电路的第一条记录类型和最后一条记录类型

SELECT opr_id,res_type,
       first_value(res_type) over(PARTITION BY opr_id ORDER BY res_type) low,
       last_value(res_type) over(PARTITION BY opr_id ORDER BY res_type rows BETWEEN unbounded preceding AND unbounded following) high
  FROM rm_circuit_route
WHERE opr_id IN ('000100190000000000021311','000100190000000000021355','000100190000000000021339')
 ORDER BY opr_id;

注:rows BETWEEN unbounded preceding AND unbounded following 的使用

--取last_value时不使用rows BETWEEN unbounded preceding AND unbounded following的结果

SELECT opr_id,res_type,
       first_value(res_type) over(PARTITION BY opr_id ORDER BY res_type) low,
       last_value(res_type) over(PARTITION BY opr_id ORDER BY res_type) high
  FROM rm_circuit_route
 WHERE opr_id IN ('000100190000000000021311','000100190000000000021355','000100190000000000021339')
 ORDER BY opr_id;

如下图可以看到,如果不使用

rows BETWEEN unbounded preceding AND unbounded following,取出的last_value由于与res_type进行进行排列,因此取出的电路的最后一行记录的类型就不是按照电路的范围提取了,而是以res_type为范围进行提取了。

 

 

在first_value和last_value中ignore nulls的使用

数据如下:

取出该电路的第一条记录,加上ignore nulls后,如果第一条是判断的那个字段是空的,则默认取下一条,结果如下所示:

--lag() over()函数用法(取出前n行数据)
lag(expresstion,<offset>,<default>)
with a as 
(select 1 id,'a' name from dual
 union
 select 2 id,'b' name from dual
 union
 select 3 id,'c' name from dual
 union
 select 4 id,'d' name from dual
 union
 select 5 id,'e' name from dual

select id,name,lag(id,1,'')over(order by name) from a;

--lead() over()函数用法(取出后N行数据)

lead(expresstion,<offset>,<default>)
with a as 
(select 1 id,'a' name from dual
 union
 select 2 id,'b' name from dual
 union
 select 3 id,'c' name from dual
 union
 select 4 id,'d' name from dual
 union
 select 5 id,'e' name from dual

select id,name,lead(id,1,'')over(order by name) from a;

--ratio_to_report(a)函数用法 Ratio_to_report() 括号中就是分子,over() 括号中就是分母
with a as (select 1 a from dual
           union all
select 1 a from dual
           union  all
select 1 a from dual
           union all
select 2 a from dual
           union all 
select 3 a from dual
           union all
select 4 a from dual
           union all
select 4 a from dual
           union all
select 5 a from dual
           )
select a, ratio_to_report(a)over(partition by a) b from a 
order by a;

with a as (select 1 a from dual
           union all
select 1 a from dual
           union  all
select 1 a from dual
           union all
select 2 a from dual
           union all 
select 3 a from dual
           union all
select 4 a from dual
           union all
select 4 a from dual
           union all
select 5 a from dual
           )
select a, ratio_to_report(a)over() b from a --分母缺省就是整个占比
order by a;

with a as (select 1 a from dual
           union all
select 1 a from dual
           union  all
select 1 a from dual
           union all
select 2 a from dual
           union all 
select 3 a from dual
           union all
select 4 a from dual
           union all
select 4 a from dual
           union all
select 5 a from dual
           )
select a, ratio_to_report(a)over() b from a
group by a order by a;--分组后的占比

--转自:https://www.cnblogs.com/yyhxqx/p/4795296.html

转: OVER() 系列函数介绍的更多相关文章

  1. openssl之EVP系列之13---EVP_Open系列函数介绍

    openssl之EVP系列之13---EVP_Open系列函数介绍     ---依据openssl doc/crypto/EVP_OpenInit.pod翻译和自己的理解写成     (作者:Dra ...

  2. openssl之EVP系列之12---EVP_Seal系列函数介绍

    openssl之EVP系列之12---EVP_Seal系列函数介绍     ---依据openssl doc/crypto/EVP_SealInit.pod翻译和自己的理解写成     (作者:Dra ...

  3. openssl之EVP系列之11---EVP_Verify系列函数介绍

    openssl之EVP系列之11---EVP_Verify系列函数介绍     ---依据openssl doc/crypto/EVP_VerifyInit.pod翻译和自己的理解写成     (作者 ...

  4. openssl之EVP系列之10---EVP_Sign系列函数介绍

    openssl之EVP系列之10---EVP_Sign系列函数介绍     ---依据openssl doc/crypto/EVP_SignInit.pod翻译     (作者:DragonKing, ...

  5. Mem系列函数介绍及案例实现

      昨天导师甩给我们一个项目案例,让我们自己去看一看熟悉一下项目内容,我看到了这个项目里面大量使用memset(sBuf,0,sizeof(sBuf));这一块内存填充的代码,于是回想起以前查过Mem ...

  6. Python开发【第三章】:Python函数介绍

    一. 函数介绍 1.函数是什么? 在学习函数之前,一直遵循面向过程编程,即根据业务逻辑从上到下实现功能,其往往用一长段代码来实现指定功能,开发过程中最常见的操作就是粘贴复制,也就是将之前实现的代码块复 ...

  7. 从简单需求到OLAP的RANK系列函数

    同事问了一个非常简单的问题,怎么取出每个partition里面另外一个列的最小值? create table t1 (int c1, int c2);   假如按照c2分区,0-10,10-20,20 ...

  8. linux tricks 之VA系列函数.

    VA函数(variable argument function),参数个数可变函数,又称可变参数函数.C/C++编程中,系统提供给编程人员的va函数很少.*printf()/*scanf()系列函数, ...

  9. 原子操作 Interlocked系列函数

    上一篇<多线程第一次亲密接触 CreateThread与_beginthreadex本质区别>中讲到一个多线程报数功能.为了描述方便和代码简洁起见,我们可以只输出最后的报数结果来观察程序是 ...

随机推荐

  1. linux 命令 — download

    wget 下载工具 一般 wget url 下载url指定的资源,日志输出到stdout,文件名称和url中指定的资源名称一致 wget url -o log -O file -o:指定日志输出到的文 ...

  2. C#计算字符串长度,汉字算两个字符

    在C#中的字符串类String中,有个Length属性表示字符串的长度,但该字段返回的是字符的个数,如果字符串中含有中文字符的话,一个汉字占用两个字符的长度,此时获取的长度就不够精确,当然也看具体业务 ...

  3. Try Catch 嵌套问题

    程序错误 问题描述: 在一个事物中,插入两张表数据,但是第一个成功,第二个失败了,没有起到所谓的事物的功能,这让我百思不得其解 问题所在: 本质上其实报错了,但是错误被吃掉了,具体来说,就是 try ...

  4. OKR20180607

    OKR---目标与关键成果法 一套明确和跟踪目标及其完成情况的管理工具和方法 OKR的主要目标是明确公司和团队的“目标”以及每个目标达成的可衡量的“关键结果”. “目标”是设定一个定性的时间目标.“关 ...

  5. SpringBoot零XML配置的Spring Boot Application

    Spring Boot 提供了一种统一的方式来管理应用的配置,允许开发人员使用属性properties文件.YAML 文件.环境变量和命令行参数来定义优先级不同的配置值.零XML配置的Spring B ...

  6. constructor C++ example

    The constructor for this class could be defined, as usual, as:   Rectangle::Rectangle (int x, int y) ...

  7. 我从Angular 2转向Vue.js, 也没有选择React

    译者按: 通过使用Angular的经历,作者已经完全转为Vue粉了!我们Fundebug目前还是用AngularJS 1,坦白说,学习曲线蛮陡的. 原文: Why we moved from Angu ...

  8. 初识 Java-监听器

    使用Listener类当java  web应用程序在web容器中运行时,在java web应用程序内部会不断发生各种事件,例如web应用的启动,暂停,销毁等.以及web应用中session开始和结束 ...

  9. JavaScript碎片—函数闭包(模拟面向对象)

    经过这几天的博客浏览,让我见识大涨,其中有一篇让我感触犹深,JavaScript语言本身是没有面向对象的,但是那些大神们却深深的模拟出来了面向对象,让我震撼不已.本篇博客就是在此基础上加上自己的认知, ...

  10. html/css的学习之路(2)

    今天我跟大家说一下html,html里面其实什么东西都可以放进去的.首先创建一个文本,改变他的后缀名为html.这时有个最重要的一点不管是html还是css都不可以用中文和符号命名. 这是html中的 ...