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

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

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行。由此可见,在面对非常海量的数据存储时,按照一定的条件建立分区,是十分有必要的。不过按照时间建立分区可能会稍微麻烦点,因为时间在不停的推进,多少年之后,你现在建立的分区就已经不可能再用了,就要添加新的分区进去,这也是一个挺讨厌的事情。

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

rank() over(partition)的使用的更多相关文章

  1. Rank() over(partition ... 分组统计的实例

    USE [NanFeng]GO/****** Object: StoredProcedure [dbo].[st_MES_RptMaterilSum] Script Date: 04/18/2016 ...

  2. Oracle分析函数-rank() over(partition by...order by...)

    select *from ( SELECT t.s#,---学号 t.c#,---课程号 T.SCCORE, ---成绩 RANK() OVER(PARTITION BY t.c# ORDER BY ...

  3. 分分钟搞懂rank() over(partition by)的使用

    一.rank() over(partition by ...order by) 解释:partition  by用于给结果集分组,如果没有指定那么它把整个结果集作为一个分组. 二.语法:ROW_NUM ...

  4. rank over partition by

    高级函数,分组排序 over: 在什么条件之上. partition by e.deptno: 按部门编号划分(分区). order by e.sal desc: 按工资从高到低排序(使用rank() ...

  5. oracle rank over partition by

    转自:https://www.cnblogs.com/wingsless/archive/2012/02/04/2338292.html rank() over(partition)的使用   有的时 ...

  6. oracle row_number() over(partition by .. order by ..)和rank() over(partition by .. order by ..) 和dense_rank() over(partition by .. order by ..)的相似点与区别

    新建一个测试表 create table dim_ia_test2(device_number varchar2(20),desc2 varchar2(20)) 插入数据后得到: 一.oracle r ...

  7. rownum, row_number(), rank() , dense_rank(), partition by ,max() keep 语句的区别与用法

    rownum,rownumber(), rank(),dense_rank()都是用来为记录分配序号的, rownum只能在orderby语句排完序后,在外层嵌套查询才能获得正确的行号,用起来相当复杂 ...

  8. MySQL中实现Oracle里面 rank()over ( PARTITION BY ORDER BY) 分类分组功能

    各班级学生成绩测试表 select * from TMP_A; 实现目的: 按照班级分类后按照分数倒序排序 采用MySQL变量简单实现,SQL如下: SELECT  a.stu_id,a.point, ...

  9. 分区函数Partition By的与row_number()的用法以及与排序rank()的用法详解(获取分组(分区)中前几条记录)

    partition by关键字是分析性函数的一部分,它和聚合函数不同的地方在于它能返回一个分组中的多条记录,而聚合函数一般只有一条反映统计值的记录,partition by用于给结果集分组,如果没有指 ...

随机推荐

  1. ArrayList源代码深入剖析

    第1部分 ArrayList介绍ArrayList底层采用数组实现,它的容量能动态增长.它继承于AbstractList,实现了List, RandomAccess, Cloneable, java. ...

  2. Android安全问题 程序锁

    导读:本文介绍如何实现对应用加锁的功能,无须root权限 某些人有时候会有这样一种需求,小A下载了个软件,只是软件中的美女过于诱惑与暴露,所以他不想让别人知道这是个什么软件,起码不想让别人打开浏 览. ...

  3. JavaScript动态操作style

    1.易错:修改元素的样式不是设置class属性,而是className属性.class是JS的一个保留关键字. 2.易错:单独修改样式的属性使用"style.属性名"3.注意在cs ...

  4. caffe简易上手指南(三)—— 使用模型进行fine tune

    之前的教程我们说了如何使用caffe训练自己的模型,下面我们来说一下如何fine tune. 所谓fine tune就是用别人训练好的模型,加上我们自己的数据,来训练新的模型.fine tune相当于 ...

  5. String.IndexOf String.IndexOf String.Substring

    String.IndexOf String.IndexOf 方法 (Char, Int32, Int32)报告指定字符在此实例中的第一个匹配项的索引.搜索从指定字符位置开始,并检查指定数量的字符位置. ...

  6. Servlet个人总结

    netstat -an ——查看端口占用情况 netstat -an ——查看是谁占用了哪个端口 端口被占用之后可以关闭端口占用程序或者在conf/server.xml修改本身使用端口 javac - ...

  7. UNICODE,GBK,UTF-8区别

    简单来说,unicode,gbk和大五码就是编码的值,而utf-8,uft-16之类就是这个值的表现形式.而前面那三种编码是一兼容的,同一个汉字,那三个码值是完全不一样的.如"汉"的uncode值与g ...

  8. service name和SID的区别

    数据库名(DB_NAME).实例名(Instance_name).以及操作系统环境变量(ORACLE_SID)  在ORACLE7.8数据库中只有数据库名(db_name)和数据库实例名(instan ...

  9. Oracle函数面试题

    1.对字符串操作的函数? 答:ASCII() –函数返回字符表达式最左端字符的ASCII 码值 CHR() –函数用于将ASCII 码转换为字符 –如果没有输入0 ~ 255 之间的ASCII 码值C ...

  10. The new Portable Class Library for SQLite z

    Microsoft Open Technologies has recently released a Portable Class Library for SQLite. Thanks to it, ...