zoukankan      html  css  js  c++  java
  • oracle rank over partition by

    转自:https://www.cnblogs.com/wingsless/archive/2012/02/04/2338292.html

    rank() over(partition)的使用

     

         有的时候会遇到这样的问题,我们需要查询一张表,而且要按照业务排序,比如我需要如下的结果:

        地区   日期    费用  产品编号   用户编号

         290 201202 258 1              s1
         290 201202 200 1              s5
         290 201202 100 1              s100
         290 201202 90   2              s7
         290 201202 88   2              s9
         290 201202 10   2              s12。 

         领导让我出一张报表,需要看到每一个业务的收费前三名是那些客户。这个时候用rank() over(partition)是一个很不错的选择。

         我的测试表就像上面例子中的表一样,不过数据稍微多一点点。给大家一个截图:

         

          可以看到我每一个项目都有5条记录,我只取前三,那么SQL如下:

          

    复制代码
    SELECT A.AREA_ID, A.ACCT_MONTH, A.FEE, A.ITEM_ID, A.USER_ID
    FROM (SELECT T.AREA_ID,
    T.ACCT_MONTH,
    T.FEE,
    T.ITEM_ID,
    T.USER_ID,
    RANK() OVER(PARTITION BY T.ITEM_ID ORDER BY T.FEE DESC) RK
    FROM TEST T) A
    WHERE RK < 4;
    复制代码

           该语句执行的结果就是上述的情况了。

           一不做二不休,我顺便查看一下该语句的执行计划好了。

           首先写一下我的建表语句:

           

    复制代码
    CREATE TABLE TEST
    (
    area_id NUMBER,
    acct_month NUMBER,
    fee NUMBER,
    item_id NUMBER
    )
    PARTITION BY LIST(area_id)
    (
    PARTITION part_290 VALUES('290'),
    PARTITION part_910 VALUES('910'),
    PARTITION part_911 VALUES('911'),
    partition part_912 values('912'),
    partition part_913 values('913'),
    partition part_914 values('914'),
    partition part_915 values('915'),
    partition part_916 values('916'),
    partition part_917 values('917'),
    partition part_919 values('919'),
    partition part_default values(default)
    )
    复制代码

          我按照地域进行了分区,其实也可以按照时间进行分区。explain一下plan:

           

          可以看到,只有10条记录的表,COST却高达4,不得不说采取这个办法会极大地降低查询的效率。但是业务上需要的话,rank() over确实是一个很好使的玩意儿。

          加两条数据进去,顺便测测分区表是否真的可以在没有索引的情况下提高一点点效率。加了两条数据,area_id是911,陕西省宝鸡市的区号:0911。语句也稍微变动一下:

    复制代码
    SELECT A.AREA_ID, A.ACCT_MONTH, A.FEE, A.ITEM_ID, A.USER_ID
    FROM (SELECT T.AREA_ID,
    T.ACCT_MONTH,
    T.FEE,
    T.ITEM_ID,
    T.USER_ID,
    RANK() OVER(PARTITION BY T.ITEM_ID ORDER BY T.FEE DESC) RK
    FROM TEST T
    WHERE t.area_id = 290) A
    WHERE RK < 4;
    复制代码

          explain一下plan:

          

          发现虽然现在是12行数据,但是因为我只查询西安市(290),所以在rows里仍旧只是10行,没有新添加的宝鸡市的2行。由此可见,在面对非常海量的数据存储时,按照一定的条件建立分区,是十分有必要的。不过按照时间建立分区可能会稍微麻烦点,因为时间在不停的推进,多少年之后,你现在建立的分区就已经不可能再用了,就要添加新的分区进去,这也是一个挺讨厌的事情。

  • 相关阅读:
    HTML中,input元素的 Disabled属性 所产生的后端无法接收数据的问题
    计算字符串中大写字母,小写字母,数字的出现次数
    实现正整数的加法计算器
    简单的用户登陆程序
    对奇偶数的处理
    如何使用循环计算1 + 2 +3 + 4 + 5 + 6 + 8 + 9 + 10的值
    计算100以内所有整数的和
    根据用户输入的月份显示对应的美食
    根据用户输入的年龄输出不同的信息
    整齐的输出一首古诗
  • 原文地址:https://www.cnblogs.com/YuyuanNo1/p/7929394.html
Copyright © 2011-2022 走看看