zoukankan      html  css  js  c++  java
  • Oracle 分组排序函数

    项目开发中,我们有时会碰到需要分组排序来解决问题的情况:
    1、要求取出按field1分组后,并在每组中按照field2排序;
    2、亦或更加要求取出1中已经分组排序好的前多少行的数据

    这里通过一张表的示例和SQL语句阐述下oracle数据库中用于分组排序函数的用法。
    1.row_number() over()
    row_number()over(partition by col1 order by col2)表示根据col1分组,在分组内部根据col2排序,而此函数计算的值就表示每组内部排序后的顺序编号(组内连续的唯一的)。
    与rownum的区别在于:使用rownum进行排序的时候是先对结果集加入伪劣rownum然后再进行排序,而此函数在包含排序从句后是先排序再计算行号码。row_number()和rownum差不多,功能更强一点(可以在各个分组内从1开始排序)。


    2.rank() over()
    rank()是跳跃排序,有两个第二名时接下来就是第四名(同样是在各个分组内)


    3.dense_rank() over()
    dense_rank()也是连续排序,有两个第二名时仍然跟着第三名。相比之下row_number是没有重复值的。

    示例:
    如有表Test,数据如下
    SQL代码:   
    CREATEDATE ACCNO MONEY
    2014/6/5 111 200
    2014/6/4 111 600
    2014/6/5 111 400
    2014/6/6 111 300
    2014/6/6 222 200
    2014/6/5 222 800
    2014/6/6 222 500
    2014/6/7 222 100
    2014/6/6 333 800
    2014/6/7 333 500
    2014/6/8 333 200
    2014/6/9 333 0

    比如要根据ACCNO分组,并且每组按照CREATEDATE排序,是组内排序,并不是所有的数据统一排序,
    用下列语句实现:

    Sql代码
    select t.*,row_number() over(partition by accno order by createDate) row_number from Test t

    查询结果如下:


    大家可以注意到ACCNO为111的记录有两个相同的CREATEDATE,用row_number函数,他们的组内计数是连续唯一的,但是如果用rank或者dense_rank函数,效果就不一样,

    如下:
    rank的sql:
    select t.*,rank() over(partition by accno order by createDate) rank from Test t

    查询结果:



    可以发现相同CREATEDATE的两条记录是两个第2时接下来就是第4.

    dense_rank的sql:
    Sql代码
    select t.*,dense_rank() over(partition by accno order by createDate) dense_rank from Test t

    查询结果:



    可以发现相同CREATEDATE的两个字段是两个第2时接下来就是第3.

    项目中特殊的业务需求可能会要求用以上三个不同的函数,具体情况具体对待。


    再比如有时会要求分组排序后分别取出各组内前多少的数据记录,sql如下:
    Sql代码
    select createDate,accno,money,row_number from (select t.*,row_number() over(partition by accno order by createDate) row_number from Test t) t1 where row_number<4


    查询结果如下:

     

  • 相关阅读:
    149. Max Points on a Line(js)
    148. Sort List(js)
    147. Insertion Sort List(js)
    146. LRU Cache(js)
    145. Binary Tree Postorder Traversal(js)
    144. Binary Tree Preorder Traversal(js)
    143. Reorder List(js)
    142. Linked List Cycle II(js)
    141. Linked List Cycle(js)
    140. Word Break II(js)
  • 原文地址:https://www.cnblogs.com/java-class/p/4726175.html
Copyright © 2011-2022 走看看