• oracle-OVER(PARTITION BY... ORDER BY...)的使用


    insert into DEMO.TEST(ID,NAME,AGE,ADDRESS) VALUES(1,'cx',1,'湖北');
    insert into DEMO.TEST(ID,NAME,AGE,ADDRESS) VALUES(1,'cx',1,'湖北');
    insert into DEMO.TEST(ID,NAME,AGE,ADDRESS) VALUES(1,'cx',0.1,'湖北');
    insert into DEMO.TEST(ID,NAME,AGE,ADDRESS) VALUES(1,'cx',0.1,'湖北');
    insert into DEMO.TEST(ID,NAME,AGE,ADDRESS) VALUES(1,'cx1',1,'湖北');
    insert into DEMO.TEST(ID,NAME,AGE,ADDRESS) VALUES(1,'cx2',1,'湖北');
    insert into DEMO.TEST(ID,NAME,AGE,ADDRESS) VALUES(1,'cx1',0.1,'湖北');
    insert into DEMO.TEST(ID,NAME,AGE,ADDRESS) VALUES(1,'cx2',0.1,'湖北');
    insert into DEMO.TEST(ID,NAME,AGE,ADDRESS) VALUES(1,'cx',1,'湖南');
    insert into DEMO.TEST(ID,NAME,AGE,ADDRESS) VALUES(1,'cx',1,'长沙');
    insert into DEMO.TEST(ID,NAME,AGE,ADDRESS) VALUES(1,'cx',0.1,'上海');
    insert into DEMO.TEST(ID,NAME,AGE,ADDRESS) VALUES(1,'cx',0.1,'长沙');
    insert into DEMO.TEST(ID,NAME,AGE,ADDRESS) VALUES(1,'cx1',1,'湖南');
    insert into DEMO.TEST(ID,NAME,AGE,ADDRESS) VALUES(1,'cx2',1,'上海');
    insert into DEMO.TEST(ID,NAME,AGE,ADDRESS) VALUES(1,'cx1',0.1,'长沙');
    insert into DEMO.TEST(ID,NAME,AGE,ADDRESS) VALUES(1,'cx2',0.1,'上海');
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    例如这是一组数据,我们对其进行查询:

    IDNAMEAGEADDRESS
    1cx1湖北
    1cx1湖北
    1cx0.1湖北
    1cx0.1湖北
    1cx11湖北
    1cx21湖北
    1cx10.1湖北
    1cx20.1湖北
    1cx1湖南
    1cx1长沙
    1cx0.1上海
    1cx0.1长沙
    1cx11湖南
    1cx21上海
    1cx10.1长沙
    1cx20.1上海

    由于数据没有完全能够标识其唯一性的,我们引入伪劣ROWNUM,来标识他们:

    select ID,NAME,AGE,ADDRESS,ROWNUM FROM DEMO.TEST;
    
    • 1
    IDNAMEAGEADDRESSROWNUM
    1cx1湖北1
    1cx1湖北2
    1cx0.1湖北3
    1cx0.1湖北4
    1cx11湖北5
    1cx21湖北6
    1cx10.1湖北7
    1cx20.1湖北8
    1cx1湖南9
    1cx1长沙10
    1cx0.1上海11
    1cx0.1长沙12
    1cx11湖南13
    1cx21上海14
    1cx10.1长沙15
    1cx20.1上海16

    OVER(ORDER BY …)的意思是以按照某个字段排序,所以和直接对表的order by效果是一样的,但是over(order by …)并不能单独使用,我们这里先使用 ROW_NUMBER() OVER (ORDER BY .. ASC)

    • row_number() :从1开始,为每一条分组记录返回一个数字;
    • OVER (ORDER BY .. ASC): 按所给字段列进行升序排列
      完整含义就是:按所给字段进行升序排列,并给排序好的字段从上往下,从1开始,为每一条数据返回一个递增的数字;
    select ID,NAME,AGE,ADDRESS,ROWNUM,row_number() over(ORDER BY age asc) FROM DEMO.TEST;
    
    • 1
    IDNAMEAGEADDRESSROWNUMROW_NUMBER()OVER(ORDERBYAGEASC)
    1cx20.1湖北81
    1cx10.1长沙152
    1cx0.1长沙123
    1cx0.1上海114
    1cx20.1上海165
    1cx10.1湖北76
    1cx0.1湖北47
    1cx0.1湖北38
    1cx21上海149
    1cx11湖南1310
    1cx21湖北611
    1cx11湖北512
    1cx1长沙1013
    1cx1湖南914
    1cx1湖北215
    1cx1湖北116

    对上述结果还是不太满意,我们想得到的是,将name值相同的放在一块展示,并且按照age进行排序,此时我们可以使用:
    row_number() over(PARTITION BY .. ORDER BY .. asc)来控制

    • PARTITION BY ..:会按照指定的字段,把相同值的排在一起,分为一个块,也就是分组
      完整含义就是:按照指定的字段,把相同值的排在一起,再按所给字段进行升序排列,并给排序好的字段从上往下,从1开始,为每一条数据返回一个递增的数字,需要注意的是,对于每一块,都是从1开始;
    select ID,NAME,AGE,ADDRESS,ROWNUM,row_number() over(PARTITION BY name ORDER BY age asc) FROM DEMO.TEST;
    
    • 1
    IDNAMEAGEADDRESSROWNUMROW_NUMBER()OVER(PARTITIONBYNAMEORDERBYAGEASC)
    1cx0.1湖北31
    1cx0.1湖北42
    1cx0.1长沙123
    1cx0.1上海114
    1cx1湖南95
    1cx1湖北26
    1cx1湖北17
    1cx1长沙108
    1cx10.1湖北71
    1cx10.1长沙152
    1cx11湖北53
    1cx11湖南134
    1cx20.1上海161
    1cx20.1湖北82
    1cx21湖北63
    1cx21上海144

    上述排序结果虽然是我们想看到的,但是我们希望如果name项目age也相同的,希望他们的排序值能够一样,这样我们可以采用另外一种方法:ROWNUM,rank() over(PARTITION BY .. ORDER BY .. asc) ;

    • ROWNUM,rank(): row_number()是按照分完组之后,组内从1开始的递增排序,而rank()是按照分完组之后,组内从1开始排序的同时会比较字段值是否一样,字段值一样的记录排序值也一样,排序值以该组第一个相同值在当前组内的具体位置确定
    select ID,NAME,AGE,ADDRESS,ROWNUM,rank() over(PARTITION BY name ORDER BY age asc) FROM DEMO.TEST;
    
    • 1
    IDNAMEAGEADDRESSROWNUMRANK()OVER(PARTITIONBYNAMEORDERBYAGEASC)
    1cx0.1湖北31
    1cx0.1湖北41
    1cx0.1长沙121
    1cx0.1上海111
    1cx1湖南95
    1cx1湖北25
    1cx1湖北15
    1cx1长沙105
    1cx10.1湖北71
    1cx10.1长沙151
    1cx11湖北53
    1cx11湖南133
    1cx20.1上海161
    1cx20.1湖北81
    1cx21湖北63
    1cx21上海143

    可以看出上述确如我们预想的一样,但是如果我们希望,排序值也能保证连续的,那么可以使用:

    • dense_rank():dense_rank()是按照分完组之后,组内从1开始排序的同时会比较字段值是否一样,字段值一样的记录排序值也一样,排序值以前一个相同值为准进行排序
    select ID,NAME,AGE,ADDRESS,ROWNUM,dense_rank() over(PARTITION BY name ORDER BY age asc) FROM DEMO.TEST;
    
    • 1
    IDNAMEAGEADDRESSROWNUMDENSE_RANK()OVER(PARTITIONBYNAMEORDERBYAGEASC)
    1cx0.1湖北31
    1cx0.1湖北41
    1cx0.1长沙121
    1cx0.1上海111
    1cx1湖南92
    1cx1湖北22
    1cx1湖北12
    1cx1长沙102
    1cx10.1湖北71
    1cx10.1长沙151
    1cx11湖北52
    1cx11湖南132
    1cx20.1上海161
    1cx20.1湖北81
    1cx21湖北62
    1cx21上海142

  • 相关阅读:
    JVM类加载机制、双亲委派和SPI机制
    springboot请求映射原理
    socket网络编程
    计算机组成原理笔记(王道考研) 第二章:数据的表示和运算1
    基于STM32的物联网体感控制机械臂
    HTML人物介绍、个人设计web前端大作业、贝聿铭人物介绍(带报告3000字)
    手把手教你使用LabVIEW人工智能视觉工具包快速实现传统Opencv算子的调用(含源码)
    IDENTITY_INSERT 设置为 OFF 时,不能为表 ‘t_user‘ 中的标识列插入显式值
    MyBatis-Plus中如何使用ResultMap
    【C++】养很多鱼,只为观察向量的生长
  • 原文地址:https://blog.csdn.net/m0_56981185/article/details/126461086