oracle的分析函数over(Partition by...)

Sql代码

over(Partition by...) 一个超级牛皮的ORACLE特有函数。

最近工作中才接触到这个功能强大而灵活的函数。

oracle的分析函数over 及开窗函数

一:分析函数over

Oracle从8.1.6开始提供分析函数,分析函数用于计算基于组的某种聚合值,它和聚合函数的不同之处是

对于每个组返回多行,而聚合函数对于每个组只返回一行。

下面通过几个例子来说明其应用。

 1:统计某商店的营业额。
date sale
1 20
2 15
3 14
4 18
5 30
规则:按天统计:每天都统计前面几天的总额
得到的结果:
DATE SALE SUM
----- -------- ------
1 20 20 --1天
2 15 35 --1天+2天
3 14 49 --1天+2天+3天
4 18 67 .
5 30 97 . 2:统计各班成绩第一名的同学信息
NAME CLASS S
----- ----- ----------------------
fda 1 80
ffd 1 78
dss 1 95
cfe 2 74
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
--
得到结果:
NAME CLASS S MM
----- ----- ---------------------- ----------------------
dss 1 95 1
gds 2 92 1
gf 3 99 1
ddd 3 99 1 注意:
1.在求第一名成绩的时候,不能用row_number(),因为如果同班有两个并列第一,row_number()只返回一个结果
2.rank()和dense_rank()的区别是:
--rank()是跳跃排序,有两个第二名时接下来就是第四名
--dense_rank()l是连续排序,有两个第二名时仍然跟着第三名 3.分类统计 (并显示信息)
A B C
-- -- ----------------------
m a 2
n a 3
m a 2
n b 2
n b 1
x b 3
x b 2
x b 4
h b 3
select a,c,sum(c)over(partition by a) from t2
得到结果:
A B C SUM(C)OVER(PARTITIONBYA)
-- -- ------- ------------------------
h b 3 3
m a 2 4
m a 2 4
n a 3 6
n b 2 6
n b 1 6
x b 3 9
x b 2 9
x b 4 9 如果用sum,group by 则只能得到
A SUM(C)
-- ----------------------
h 3
m 4
n 6
x 9
无法得到B列值 =====
select * from test 数据:
A B C
1 1 1
1 2 2
1 3 3
2 2 5
3 4 6 ---将B栏位值相同的对应的C 栏位值加总
select a,b,c, SUM(C) OVER (PARTITION BY B) C_Sum
from test A B C C_SUM
1 1 1 1
1 2 2 7
2 2 5 7
1 3 3 3
3 4 6 6 ---如果不需要已某个栏位的值分割,那就要用 null eg: 就是将C的栏位值summary 放在每行后面 select a,b,c, SUM(C) OVER (PARTITION BY null) C_Sum
from test A B C C_SUM
1 1 1 17
1 2 2 17
1 3 3 17
2 2 5 17
3 4 6 17 求个人工资占部门工资的百分比 SQL> select * from salary; NAME DEPT SAL
---------- ---- -----
a 10 2000
b 10 3000
c 10 5000
d 20 4000 SQL> select name,dept,sal,sal*100/sum(sal) over(partition by dept) percent from salary; NAME DEPT SAL PERCENT
---------- ---- ----- ----------
a 10 2000 20
b 10 3000 30
c 10 5000 50
d 20 4000 100 二:开窗函数
开窗函数指定了分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变化而变化,举例如下:
1:
over(order by salary) 按照salary排序进行累计,order by是个默认的开窗函数
over(partition by deptno)按照部门分区
2:
over(order by salary range between 5 preceding and 5 following)
每行对应的数据窗口是之前行幅度值不超过5,之后行幅度值不超过5
例如:对于以下列
aa
1
2
2
2
3
4
5
6
7
9 sum(aa)over(order by aa range between 2 preceding and 2 following)
得出的结果是
AA SUM
---------------------- -------------------------------------------------------
1 10
2 14
2 14
2 14
3 18
4 18
5 22
6 18
7 22
9 9 就是说,对于aa=5的一行 ,sum为 5-1<=aa<=5+2 的和
对于aa=2来说 ,sum=1+2+2+2+3+4=14 ;
又如 对于aa=9 ,9-1<=aa<=9+2 只有9一个数,所以sum=9 ; 3:其它:
over(order by salary rows between 2 preceding and 4 following)
每行对应的数据窗口是之前2行,之后4行
4:下面三条语句等效:
over(order by salary rows between unbounded preceding and unbounded following)
每行对应的数据窗口是从第一行到最后一行,等效:
over(order by salary range between unbounded preceding and unbounded following)
等效
over(partition by null) 常用的分析函数如下所列: row_number() over(partition by ... order by ...)
rank() over(partition by ... order by ...)
dense_rank() over(partition by ... order by ...)
count() over(partition by ... order by ...)
max() over(partition by ... order by ...)
min() over(partition by ... order by ...)
sum() over(partition by ... order by ...)
avg() over(partition by ... order by ...)
first_value() over(partition by ... order by ...)
last_value() over(partition by ... order by ...)
lag() over(partition by ... order by ...)
lead() over(partition by ... order by ...) 示例
SQL> select type,qty from test; TYPE QTY
---------- ----------
1 6
2 9 SQL> select type,qty,to_char(row_number() over(partition by type order by qty))||'/'||to_char(count(*) over(partition by type)) as cnt2 from test; TYPE QTY CNT2
---------- ---------- ------------
3 1/2
1 6 2/2
2 5 1/3
7 2/3
2 9 3/3 SQL> select * from test;
---------- -------------------------------------------------
1 11111
2 22222
3 33333
4 44444 SQL> select t.id,mc,to_char(b.rn)||'/'||t.id)e
2 from test t,
(select rownum rn from (select max(to_number(id)) mid from test) connect by rownum <=mid ))L
4 where b.rn<=to_number(t.id)
order by id ID MC TO_CHAR(B.RN)||'/'||T.ID
--------- -------------------------------------------------- ---------------------------------------------------
1 11111 1/1
2 22222 1/2
2 22222 2/2
3 33333 1/3
3 33333 2/3
3 33333 3/3
44444 1/4 44444 2/4
4 44444 3/4CNOUG4 44444 4/4 10 rows selected *******************************************************************

2,rank over 说明

排序:

---rank()over(order by 列名 排序)的结果是不连续的,如果有4个人,其中有3个是并列第1名,那么最后的排序结果结果如:1 1 1 4
select scoreid, studentid,COURSENAME,totalexamscore ,
rank()over(order by TOTALEXAMSCORE desc)orderbyNum
from SCORECOURSE a ,COURSESCORE b
where a.SCORECOURSEID = b.SCORECOURSEID

---dense_rank()over(order by 列名 排序)的结果是连续的,如果有4个人,其中有3个是并列第1名, 那么最后的排序结果如:1 1 1 2
select scoreid, studentid,COURSENAME,totalexamscore ,
dense_rank()over(order by TOTALEXAMSCORE desc)orderbyNum
from SCORECOURSE a ,COURSESCORE b
where a.SCORECOURSEID = b.SCORECOURSEID

----rank () OVER (PARTITION BY 列名 ORDER BY 列名 排序)使用分区方式获取每门课程的最高分
SELECT *
  FROM (SELECT scoreid, studentid, coursename, TOTALEXAMSCORE,
               rank () OVER (PARTITION BY coursename ORDER BY TOTALEXAMSCORE DESC)orderbynum
          FROM scorecourse a, coursescore b
         WHERE a.scorecourseid = b.scorecourseid and studentID = 'xxxxx')
 WHERE orderbynum < 2

-----使用over实现成绩求和
-----SUM (totalexamscore) OVER (ORDER BY studentid) sum1  实现的是连续求和,如第一个学生的总评成绩是30,则sum1就展示为30,到第二个学生成绩出现的时候,则会依次累加
-----SUM (totalexamscore) OVER () sum2 就相当于是单纯的求和,和直接使用sum是一致的
SELECT scoreid, studentid, totalexamscore,
       SUM (totalexamscore) OVER (ORDER BY studentid) sum1,
       SUM (totalexamscore) OVER () sum2
  FROM coursescore
注:这个案例想了很久也没想到很直观的描述,还请大家亲自去测试一下吧!!

语法:
rank() over (order by 排序字段 顺序)
rank() over (partition by 分组字段 order by 排序字段 顺序)

1.顺序:asc|desc  名次与业务相关:
  示例:求优秀学员,成绩:降序  迟到次数:升序
2.分区字段:根据什么字段进行分区。

问题:分区与分组有什么区别?
•分区只是将原始数据进行名次排列(记录数不变),
•分组是对原始数据进行聚合统计(记录数变少,每组返回一条)。

注意:使用rank()over(order by 排序字段 顺序)排序的时候,空值是最大的
(如果排序字段为null,可能造成在排序时将null字段排在最前面,影响排序的正确性。
所以建议将dense_rank()over(order by 列名 排序)改为dense_rank()over(order by 列名 排序 nulls last)
这样只要排序字段为null,就会放在最后,而不会影响排序结果).

Oracle分析函数简析的更多相关文章

  1. oracle函数简析

    (一).数值型函数(Number Functions) 数值型函数输入数字型参数并返回数值型的值.多数该类函数的返回值支持38位小数点,诸如:COS, COSH, EXP, LN, LOG, SIN, ...

  2. ORACLE时间函数(SYSDATE)简析

    ORACLE时间函数(SYSDATE)简析 分类: 原文地址:ORACLE时间函数(SYSDATE)简析 作者:skylway 加法 select sysdate,add_months(sysdate ...

  3. Oracle分析函数入门

    一.Oracle分析函数入门 分析函数是什么?分析函数是Oracle专门用于解决复杂报表统计需求的功能强大的函数,它可以在数据中进行分组然后计算基于组的某种统计值,并且每一组的每一行都可以返回一个统计 ...

  4. [转]oracle分析函数Rank, Dense_rank, row_number

    oracle分析函数Rank, Dense_rank, row_number 分析函数2(Rank, Dense_rank, row_number)   目录 ==================== ...

  5. [转]oracle 分析函数over

      oracle 分析函数over 分析函数(OVER) 目录: =============================================== 1.Oracle分析函数简介 2. O ...

  6. 简析.NET Core 以及与 .NET Framework的关系

    简析.NET Core 以及与 .NET Framework的关系 一 .NET 的 Framework 们 二 .NET Core的到来 1. Runtime 2. Unified BCL 3. W ...

  7. 简析 .NET Core 构成体系

    简析 .NET Core 构成体系 Roslyn 编译器 RyuJIT 编译器 CoreCLR & CoreRT CoreFX(.NET Core Libraries) .NET Core 代 ...

  8. oracle分析函数与over()(转)

    文章参考:http://blog.csdn.net/haiross/article/details/15336313 -- Oracle分析函数入门-- 分析函数是什么? 分析函数是Oracle专门用 ...

  9. RecycleView + CardView 控件简析

    今天使用了V7包加入的RecycleView 和 CardView,写篇简析. 先上效果图: 原理图: 这是RecycleView的工作原理: 1.LayoutManager用来处理RecycleVi ...

随机推荐

  1. CSU 1862 The Same Game(模拟)

    The Same Game [题目链接]The Same Game [题目类型]模拟 &题解: 写这种模拟题要看心态啊,还要有足够的时间,必须仔细读题,一定要写一步,就调试一步. 这题我没想到 ...

  2. Lambda引言

    Lambda表达式:可以方便我们把方法当做参数传递 package airycode_java8.nice1; import org.junit.Test; import java.util.*; / ...

  3. TP引用样式表和js文件及验证码

    TP引用样式表和js文件及验证码 引入样式表和js文件 <script src="__PUBLIC__/bootstrap/js/jquery-1.11.2.min.js"& ...

  4. Unity shader学习之屏幕后期处理效果之Bloom效果

    Bloom特效是游戏中常见的一种屏幕效果.这种特效可以模拟真实摄像机的一种图像效果,它让画面中较亮的区域“扩散”到周围的区域中,造成一种朦胧的效果. Bloom的实现原理很简单,首先根据一个阈值提取出 ...

  5. leetCodelinked-list-cycle-ii找到链表的环

    题目 Given a linked list, return the node where the cycle begins. If there is no cycle, return null. N ...

  6. 6.Daemon线程

    1.如下代码: package com.bawei.multithread; public class Recursive { private static int counter = 0; publ ...

  7. spring4.0.0 源码导入eclipse(sts)

    其余步骤请见:http://www.cnblogs.com/xiluhua/p/7450972.html 执行 gradle eclipse -x :eclipse 报错: 解决办法: 找到 行,注释 ...

  8. Presto 学习和使用笔记

    1.presto 表连接查询的连接条件中不支持使用函数 比如下面的脚本在presto中运行会报错 select t1.period_start_date, t2.statistic_date from ...

  9. localStorage过期策略

    localStorage过期策略 由于html5没有给本地存储设置过期策略,那么在处理数据的过期策略的时候可以编写自己过期策略程序,如下: <!DOCTYPE> <head> ...

  10. 听 Fabien Potencier 谈Symfony2 之 《What is Dependency Injection ?》

    听 Fabien Potencier 谈Symfony2 之 <What is Dependency Injection ?>   什么是依赖注入?从PHP实现角度来分析依赖注入,因为PH ...