当前位置:  数据库>oracle

实现Top-N查询的几种方法

    来源: 互联网  发布时间:2017-05-04

    本文导语: Top-N查询用于从一个有序的结果集中返回有限的记录数。当需要取得最前面或最后面N条记录,抑或需要对数据进行分页查看时,该查询尤其有用。本文将介绍几种实现Top-N查询的方法。 首先创建测试表并插入20行数据,但只有10...

Top-N查询用于从一个有序的结果集中返回有限的记录数。当需要取得最前面或最后面N条记录,抑或需要对数据进行分页查看时,该查询尤其有用。本文将介绍几种实现Top-N查询的方法。
 
首先创建测试表并插入20行数据,但只有10个不同的值。
DROP TABLE rownum_order_test;
 
CREATE TABLE rownum_order_test (
 val NUMBER
);
 
INSERT ALL
 INTO rownum_order_test
 INTO rownum_order_test
SELECT level
FROM  dual
CONNECT BY level
 
COMMIT;
 
记得不要这么做!
如果不知道伪列ROWNUM和ORDER BY子句的相互影响,下面的例子是人们通常会掉进去的一个陷阱。假设需要返回前5个最大的ID,则先按ID降序排列,然后选取前5个值。
这听上去完全没问题,所以我们按照这个思路得到如下查询。
SELECT val
FROM  rownum_order_test
WHERE rownum
ORDER BY val DESC;
 
      VAL
----------
        5
        4
        3
        2
        1
 
5 rows selected.
这不是我们要的!
出现这个结果的原因是ROWNUM的分配时先于ORDER BY进行的,这导致该查询会随机返回5行。
 
1.使用内联视图和ROWNUM
最经典的Top-N查询是通过一个内联查询将数据按照要求排序,然后用ROWNUM来限制返回的数据。
SELECT val
FROM  (SELECT val
       FROM  rownum_order_test
       ORDER BY val DESC)
WHERE ROWNUM
 
      VAL
----------
       10
       10
        9
        9
        8
5 rows selected.
 
由于数据在进行ROWNUM检查前已经具有了我们希望的顺序,所以返回了我们相要的结果。但是,我们要5行,也只得到了5行,虽然表中还有一个8。
 
该方法也可以用来分页查询数据。
SELECT val
FROM  (SELECT val, rownum AS rnum
       FROM  (SELECT val
               FROM  rownum_order_test
               ORDER BY val)
       WHERE rownum
WHERE rnum >= 4;
 
      VAL
----------
        2
        3
        3
        4
        4
 
5 rows selected.
 
2.使用RANK实现
分析函数RANK给窗口范围内的每个不同值分配一个连续的序号。
SELECT val
FROM  (SELECT val,
              RANK() OVER (ORDER BY val DESC) AS val_rank
       FROM  rownum_order_test)
WHERE val_rank
 
      VAL
----------
       10
       10
        9
        9
        8
        8
 
6 rows selected.
返回了6行?
把RANK函数分配的序号显示出来,结果就一目了然了。
SELECT val, val_rank
FROM  (SELECT val,
              RANK() OVER (ORDER BY val DESC) AS val_rank
       FROM  rownum_order_test)
WHERE val_rank
 
      VAL  VAL_RANK
---------- ----------
       10         1
       10         1
        9         3
        9         3
        8         5
        8         5
 
6 rows selected.
从上可以看出,RANK给重复行分配相同的序号且序号有跳跃,每一个新序号出现时与其实际行数保持一致。所以RANK函数并不会给出前N行数据或前N个不同的值。返回的行数依赖于表中数据的重复情况。
 
3.使用DENSE_RANK实现
分析函数DENSE_RANK和RANK函数有几分相像,该函数也为每个不同的值分配一个序号。不同的是,该函数产生的序号不存在跳跃性。
SELECT val, val_rank
FROM  (SELECT val,
              DENSE_RANK() OVER (ORDER BY val DESC) AS val_rank
       FROM  rownum_order_test)
WHERE val_rank
 
      VAL  VAL_RANK
---------- ----------
       10         1
       10         1
        9         2
        9         2
        8         3
        8         3
        7         4
        7         4
        6         5
        6         5
 
10 rows selected.
如上所示,该函数永远会给出前N个不同的值。
 
4.使用ROW_NUMBER函数实现
分析函数ROW_NUMBER的行为与伪列ROWNUM相似,它为返回的每一行分配不同的序号。
SELECT val
FROM  (SELECT val,
              ROW_NUMBER() OVER (ORDER BY val DESC) AS val_row_number
       FROM  rownum_order_test)
WHERE val_row_number
 
      VAL
----------
       10
       10
        9
        9
        8
 
5 rows selected.


























































































































































    
 
 

您可能感兴趣的文章:

  • html<pre>标签自动换行实现方法
  • 求在freebsd+Squid下实现pc上网的透明代理的实现方法!给出具体配置方法的高分谢!
  • java tomcat实现Session对象的持久化原理及配置方法介绍
  • 菜鸟提问:一个类实现了一个接口,除了要定义接口的所有方法外,可不可以再添加其他方法?
  • Session id实现通过Cookie来传输方法及代码参考
  • 实现在同一方法中获取当前方法中新赋值的session值解决方法
  • JavaScript实现页面跳转的几种方法(参考代码)
  • 弱智问题:我们怎么才知道要使用的方法需要实现什么接口才能使用这个方法呢?
  • java实现判断字符串是否全是数字的四种方法代码举例
  • 自己实现strcpy函数的实现方法
  • 网站到底怎么实现盈利赚钱:个人网站赚钱方法大总结
  • php通过数组实现多条件查询实现方法(字符串分割)
  • java 与 C++ 实现后绑定的方法
  • 在Servlet中方法doGet和doPost分别实现什么功能,Html中表单的get、post方法我就不明白
  • DevExpress实现GridControl显示Gif动画的方法
  • Collections.sort()方法,已经实现Comparable接口,为什么无法将Vector排序?
  • C#实现获取枚举中元素个数的方法
  • 请问聊天室中显示用户在线离线的原理是怎样?有哪些方法实现呢?
  • 请问jdk源程序中,许多native方法是怎么实现的?
  • c# 重载WndProc,实现重写“最小化”的实现方法
  • mysql中文排序注意事项与实现方法
  • 问:如何实现组合查询?
  • mysqli多查询特性 实现多条sql语句查询
  • 我想把csdn的论坛改成一个软件平台,另外增加数据查询功能,聊天功能,不知怎样实现比较好?我想用jbuider 7+SQL server实现,不知如何?
  • 网络技术 iis7站长之家
  • Linq实现的简单查询的例子
  • 谁用过ejb 进行模糊查询???语句怎么写???能实现根据中间的字符串进行模糊查找么?
  • python实现DNS正向查询、反向查询的例子
  • 要实现同样的一个问题,例如数据库的查询操作,并将结果返回到页面中,在Servlet与JavaBean中都可以写相同的数据库查询操作的代码,那么
  • 数据库查询分页技术实现,java 类 Vector() 在哪个包下?
  • 怎样实现汉字的拼音首字母查询!(在线等待)
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • 通过javascript实现DIV居中,兼容各浏览器版本
  • socket实现多文件并发传输,求助多线程实现问题?
  • Python GUI编程:tkinter实现一个窗口并居中代码
  • interface 到底有什么用???实现接口,怎么实现??
  • 通过javascript库JQuery实现页面跳转功能代码
  • 怎么用Jsp实现在页面实现树型结构?
  • sharepoint 2010 使用STSNavigate函数实现文件下载举例
  • windows 下的PortTunnel 在linux下怎么实现?或者相应的已经实现的软件?端口映射
  • php实现socket实现客户端和服务端数据通信源代码
  • 网站重定向用C语言实现iptables,ACL实现
  • flash AS3反射实现(describeType和getDefinitionByName)
  • 在linux下如何编程实现nslookup命令实现的IP地址和域名互相转换的功能?
  • boost unordered_map和std::list相结合的实现LRU算法
  • linux下如实现与window下的驱动器实现文件共享??
  • c#通过委托delegate与Dictionary实现action选择器代码举例
  • qt如何实现:操作键盘实现数据的滚动?
  • 使用java jdk中的LinkedHashMap实现简单的LRU算法
  • 我想用APPLET实现读取客户端的图片文件,该如何实现?
  • iphone cocos2d 精灵的动画效果(图片,纹理,帧)CCAnimation实现
  • PING是用TCP,还是用UDP来实现的?或是采用其它协议实现的?
  • c语言判断某一年是否为闰年的各种实现程序代码
  • ejb-ql只能 like '?%' 么?我想实现模糊查寻,想实现 like'%?%' 怎么办??


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,