• oracle—排名函数与窗口函数


    一、排名函数

    1.rank()——跳跃排名

    按照年龄进行排名;

    SQL> select * from employees ;
     
    EMPLOYEE_ID EMPLOYEE_NAME EMPLOYEE_POSITION EMPLOYEE_AGE EMPLOYEE_ADD         EMPLOYEE_BIRTH
    ----------- ------------- ----------------- ------------ -------------------- --------------
    10          江小白                                                            
    4           大鳄          工程师                      26 巴南                 1988-07-01
    3           昂呜          高级工程师                  27 渝北                 1998-06-01
    2           李四          高级工程师                  32 渝北                 1994-09-01
    1           张三          开发经理                    37 巴南                 1987-11-01
    5           过户          工程师                      26 渝中                 1985-08-01
    6           问题          工程师                      25 渝中                 1980-02-09
    7           语句          测试工程师                  24 九龙坡               2010-05-03
    8           陈武          测试工程师                  25 江北                 2004-01-23
    9           六六          测试工程师                  32 南岸                 1994-12-21
     
    10 rows selected
     
    SQL> select employee_name,employee_age,rank() over(order by employee_age) rank_age from employees ;
     
    EMPLOYEE_NAME EMPLOYEE_AGE   RANK_AGE
    ------------- ------------ ----------
    语句                    24          1
    陈武                    25          2
    问题                    25          2
    大鳄                    26          4
    过户                    26          4
    昂呜                    27          6
    李四                    32          7
    六六                    32          7
    张三                    37          9
    江小白                             10
     
    10 rows selected
    View Code

    2.dense_rank——不跳跃排名

    按照年龄进行排名;

    SQL> select employee_name,employee_age,dense_rank() over(order by employee_age) rank_age from employees ;
     
    EMPLOYEE_NAME EMPLOYEE_AGE   RANK_AGE
    ------------- ------------ ----------
    语句                    24          1
    陈武                    25          2
    问题                    25          2
    大鳄                    26          3
    过户                    26          3
    昂呜                    27          4
    李四                    32          5
    六六                    32          5
    张三                    37          6
    江小白                              7
     
    10 rows selected
    View Code

    3.row_number()——排序

    按照年龄进行排名;

    SQL> select employee_name,employee_age,row_number() over(order by employee_age) rank_age from employees ;
     
    EMPLOYEE_NAME EMPLOYEE_AGE   RANK_AGE
    ------------- ------------ ----------
    语句                    24          1
    陈武                    25          2
    问题                    25          3
    大鳄                    26          4
    过户                    26          5
    昂呜                    27          6
    李四                    32          7
    六六                    32          8
    张三                    37          9
    江小白                             10
     
    10 rows selected
    View Code

    二、窗口函数

    求各岗位的平均年龄

    SQL> select employee_name,employee_position,avg(employee_age) over(partition by employee_position) rank_age from employees ;
     
    EMPLOYEE_NAME EMPLOYEE_POSITION   RANK_AGE
    ------------- ----------------- ----------
    陈武          测试工程师                27
    六六          测试工程师                27
    语句          测试工程师                27
    昂呜          高级工程师              29.5
    李四          高级工程师              29.5
    大鳄          工程师            25.6666666
    过户          工程师            25.6666666
    问题          工程师            25.6666666
    张三          开发经理                  37
    江小白                          
     
    10 rows selected
    View Code

    各岗位按年龄排名

    SQL> select employee_name,employee_position,employee_age,dense_rank() over(partition by employee_position order by employee_age) rank_age from employees ;
     
    EMPLOYEE_NAME EMPLOYEE_POSITION EMPLOYEE_AGE   RANK_AGE
    ------------- ----------------- ------------ ----------
    语句          测试工程师                  24          1
    陈武          测试工程师                  25          2
    六六          测试工程师                  32          3
    昂呜          高级工程师                  27          1
    李四          高级工程师                  32          2
    问题          工程师                      25          1
    大鳄          工程师                      26          2
    过户          工程师                      26          2
    张三          开发经理                    37          1
    江小白                                                1
     
    10 rows selected
    View Code

    三、窗口子句

    使用前须对窗口内的数据进行排序。

    1.rows子句

    语法:over(order by 列名 rows between 位移量 preceding and  位移量  following)

    需求:获取当前员工前一位、后一位员工年龄和。

    SQL> select employee_name,employee_position,employee_age,sum(employee_age) over(order by employee_age rows between 1 preceding and 1 following) rank_age from employees ;
     
    EMPLOYEE_NAME EMPLOYEE_POSITION EMPLOYEE_AGE   RANK_AGE
    ------------- ----------------- ------------ ----------
    语句          测试工程师                  24         49
    陈武          测试工程师                  25         74
    问题          工程师                      25         76
    大鳄          工程师                      26         77
    过户          工程师                      26         79
    昂呜          高级工程师                  27         85
    李四          高级工程师                  32         91
    六六          测试工程师                  32        101
    张三          开发经理                    37         69
    江小白                                               37
     
    10 rows selected
    View Code

    2.range子句

    语法:over(order by 列名 range between 差值 preceding and  差值  following)

    需求:

    SQL> select employee_name,employee_position,employee_age,count(1) over(order by employee_age range between 1 preceding and 1 following) rank_age from employees ;
     
    EMPLOYEE_NAME EMPLOYEE_POSITION EMPLOYEE_AGE   RANK_AGE
    ------------- ----------------- ------------ ----------
    语句          测试工程师                  24          3
    陈武          测试工程师                  25          5
    问题          工程师                      25          5
    大鳄          工程师                      26          5
    过户          工程师                      26          5
    昂呜          高级工程师                  27          3
    李四          高级工程师                  32          2
    六六          测试工程师                  32          2
    张三          开发经理                    37          1
    江小白                                                1
     
    10 rows selected
    View Code

    3.current row与unbounded

    需求:获取第一条记录至当前窗口大小

    SQL> select employee_name,employee_position,employee_age,count(1) over(order by employee_age rows between unbounded preceding and current row) last_value from employees;
     
    EMPLOYEE_NAME EMPLOYEE_POSITION EMPLOYEE_AGE LAST_VALUE
    ------------- ----------------- ------------ ----------
    语句          测试工程师                  24          1
    陈武          测试工程师                  25          2
    问题          工程师                      25          3
    大鳄          工程师                      26          4
    过户          工程师                      26          5
    昂呜          高级工程师                  27          6
    李四          高级工程师                  32          7
    六六          测试工程师                  32          8
    张三          开发经理                    37          9
    江小白                                               10
     
    10 rows selected
    View Code

    需求:不限制当前窗口

    SQL> select employee_name,employee_position,employee_age,count(1) over(order by employee_age rows between unbounded preceding and unbounded following) last_value from employees;
     
    EMPLOYEE_NAME EMPLOYEE_POSITION EMPLOYEE_AGE LAST_VALUE
    ------------- ----------------- ------------ ----------
    语句          测试工程师                  24         10
    陈武          测试工程师                  25         10
    问题          工程师                      25         10
    大鳄          工程师                      26         10
    过户          工程师                      26         10
    昂呜          高级工程师                  27         10
    李四          高级工程师                  32         10
    六六          测试工程师                  32         10
    张三          开发经理                    37         10
    江小白                                               10
     
    10 rows selected
    View Code

    四、分析函数

    1.first_value()——排序窗口中第一条数据。

    获取同龄人中姓名靠前的名字

    SQL> select employee_name,employee_age,first_value(employee_name) over(partition by employee_age order by employee_name) first_value from employees ;
     
    EMPLOYEE_NAME EMPLOYEE_AGE FIRST_VALUE
    ------------- ------------ -----------
    语句                    24 语句
    陈武                    25 陈武
    问题                    25 陈武
    大鳄                    26 大鳄
    过户                    26 大鳄
    昂呜                    27 昂呜
    李四                    32 李四
    六六                    32 李四
    张三                    37 张三
    江小白                     江小白
     
    10 rows selected
    View Code

    2.last_value()——排序窗口中最后一条数据。

    SQL> select employee_name,employee_age,last_value(employee_name) over(partition by employee_age order by employee_name) last_value from employees ;
     
    EMPLOYEE_NAME EMPLOYEE_AGE LAST_VALUE
    ------------- ------------ ----------
    语句                    24 语句
    陈武                    25 陈武
    问题                    25 问题
    大鳄                    26 大鳄
    过户                    26 过户
    昂呜                    27 昂呜
    李四                    32 李四
    六六                    32 六六
    张三                    37 张三
    江小白                     江小白
     
    10 rows selected
     
    SQL> select employee_name,employee_age,last_value(employee_name) over(partition by employee_age order by employee_name rows between unbounded preceding and unbounded following) last_value from employees ;
     
    EMPLOYEE_NAME EMPLOYEE_AGE LAST_VALUE
    ------------- ------------ ----------
    语句                    24 语句
    陈武                    25 问题
    问题                    25 问题
    大鳄                    26 过户
    过户                    26 过户
    昂呜                    27 昂呜
    李四                    32 六六
    六六                    32 六六
    张三                    37 张三
    江小白                     江小白
     
    10 rows selected
    View Code

    第一条SQL,由于窗口为默认窗口;借助rows子句指定无限制窗口来实现。也可以通过order by desc来获取。

    3.lag()——获取向前的记录

    语法:lag(列名,位移,默认值)  

    需求:获取前一位员工信息。

    SQL> select employee_name,employee_age,lag(employee_name,1,'N/A') over(order by employee_age) lag_name,lag(employee_age,1,null) over(order by employee_age) lag_age from employees ;
     
    EMPLOYEE_NAME EMPLOYEE_AGE LAG_NAME    LAG_AGE
    ------------- ------------ -------- ----------
    语句                    24 N/A      
    陈武                    25 语句             24
    问题                    25 陈武             25
    大鳄                    26 问题             25
    过户                    26 大鳄             26
    昂呜                    27 过户             26
    李四                    32 昂呜             27
    六六                    32 李四             32
    张三                    37 六六             32
    江小白                     张三             37
     
    10 rows selected
    View Code

    4.lead()——获取向后的记录

    语法:lead(列名,位移,默认值)  

    需求:获取后一位员工信息

    SQL> select employee_name,employee_age,lead(employee_name,1,'N/A') over(order by employee_age) lead_name,lead(employee_age,1,null) over(order by employee_age) lead_age from employees ;
     
    EMPLOYEE_NAME EMPLOYEE_AGE LEAD_NAME   LEAD_AGE
    ------------- ------------ --------- ----------
    语句                    24 陈武              25
    陈武                    25 问题              25
    问题                    25 大鳄              26
    大鳄                    26 过户              26
    过户                    26 昂呜              27
    昂呜                    27 李四              32
    李四                    32 六六              32
    六六                    32 张三              37
    张三                    37 江小白    
    江小白                     N/A       
     
    10 rows selected
    View Code

     整理于《oracle入门很简单》一书

  • 相关阅读:
    yield* 表达式
    Set 对象和WeakSet对象
    洗牌算法
    filter() 方法创建一个新数组
    UTF8文件带BOM引起的问题
    ios的白屏坑
    css的字体样式怎么写
    npm全局安装失效修复
    nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)解决方案
    linux下nginx的安装及配置
  • 原文地址:https://www.cnblogs.com/zs-chenkang/p/13932357.html
Copyright © 2020-2023  润新知