Oracle over(partition by)函数的用法

主要介绍over(partition by)的使用过程于group by 和partition by的区别

现有数据结构如下:

create table ABCS
(
  UPDATE_DATE           DATE not null,--日期
  EMPOLYEE_NAME         NVARCHAR2(80),--人员
  SALARY                       NUMBER --薪资
)

INSERT INTO ABCS VALUES (2020/7/1,    张三,    12);
INSERT INTO ABCS VALUES (2020/7/2,    张三,    11);
INSERT INTO ABCS VALUES (2020/7/2,    李四,    20);
INSERT INTO ABCS VALUES (2020/7/1,    张三,    20);
INSERT INTO ABCS VALUES (2020/7/1,    张三,    20);
INSERT INTO ABCS VALUES (2020/6/1,    张三,    12);
INSERT INTO ABCS VALUES (2020/6/1,    李四,    10);
INSERT INTO ABCS VALUES (2020/6/2,    张三,    11);
INSERT INTO ABCS VALUES (2020/6/2,    李四,    20);
INSERT INTO ABCS VALUES (2020/6/1,    张三,    20);

需求:取时间最大的一条记录显示

不用over(patition by)函数:

  • 1.根据MAX()过滤出最大的时间取第一条。
select t.update_date,
       t.salary,
       t.empolyee_name  
  from abcs t 
  where t.update_date=(select max(t.update_date) from abcs t)  
    and rownum=1 

运行结果:能找出时间都是最大的所有数据,加上rownum=1就是选其中一条。

  • 2.排序后取第一条。
select *
  from (select t.update_date, t.salary, t.empolyee_name
          from abcs t
         order by t.update_date desc)
 where rownum = 1

运行结果:与1相比建议用这条查一条数据的,数据量大的话

 

以上是只能显示一条数据的,下面来看数据量大,多条重复数据,根据分组排序取一条显示。

用over(patition by)函数:

  • 3.row_number()  over(partition by 分组字段  order by 排序字段   排序方式) 
 
 SELECT *
   FROM (select t.update_date,
                t.salary,
                t.empolyee_name,
                row_number() over(partition by t.empolyee_name order by t.update_date desc) mm
           from abcs t)
  where mm = 1;

运行结果:可以看到包装在里面的SQL是根据时间排序,根据人员分组,然后选择mm=1排在第一位的数据

  • 4.rank()  over(partition by 分组字段  order by 排序字段   排序方式) 
 SELECT *
   FROM (select t.update_date,
                t.salary,
                t.empolyee_name,
                rank() over(partition by t.empolyee_name order by t.update_date asc) mm
           from abcs t)
  where mm = 1;

运行结果:首先为了与3做一个区分,可以看到当排序的字段与分组的字段一致时,mm的值会相等,这就是rank()与row_number()不一样的地方,刚好这个排序在最末尾那我们把DESC换成ASC后得到上面的代码段再运行看看,再选择mm=1的时候张三的那组就有两条数据了。

  • 5.dense_rank() over(partition by 分组字段  order by 排序字段   排序方式) 
 SELECT *
   FROM (select t.update_date,
                t.salary,
                t.empolyee_name,
                dense_rank() over(partition by t.empolyee_name order by t.update_date desc
                ) mm
           from abcs t)
  where mm = 1;

运行结果:dense_rank()是连续排序,与4比较会发现虽然会有两个mm=2的行还是会按循序从3开始排列。

  • 6.sum(汇总字段) over(partition by 分组字段  order by 排序字段   排序方式) 
__一般SUM函数的用法:根据用户分组汇总 

select t.empolyee_name, sum(t.salary)
    from abcs t
   group by t.empolyee_name

过程分析

A.sum(汇总字段) over(order by 排序字段),通过下面的列子可以看到根据排序字段(t.update_date)依次累加。

select t.update_date,
          t.salary,
          t.empolyee_name,
          sum(t.salary) over(order by t.update_date) as sumQty
     from abcs t

B.sum(汇总字段) over(partition by 分组字段 order by 排序字段),加上分组之后可以看到运行结果是先分组后再根据排序字段进行累加

select t.update_date,
          t.salary,
          t.empolyee_name,
          sum(t.salary) over(partition by t.empolyee_name order by t.update_date) as sumQty
     from abcs t

C.sum(汇总字段) over(partition by 分组字段 ),去掉排序的,分组的汇总字段会一次性汇总。如果B列中分组字段和排序字段相同那么跟C的效果是一样的。如果其他字段一样还加上去重distinct只显示一条。

select t.update_date,
          t.salary,
          t.empolyee_name,
          sum(t.salary) over(partition by t.empolyee_name ) as sumQty
     from abcs t

以上两种分组group by 和partition by的区别:partition by在增加排序后能对排序字段进行累加

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值