如果选择踏足,终有一天你会爱上这条路。

今天讲讲ORACLE中关于ROWNUM的用法:

一、简单介绍一下ROWNUM是什么,可以用来干什么。

答:ROWNUM是一个序列,会根据sql语句自动给你加上一列排好顺序的序号列。For example!

你有一张全班同学的各科目成绩表。

1、然后你想给这张表按语文成绩加上排名。你会怎么做?

SELECT G.ID, G.NAME, G.CHINESE, ROWNUM AS CHINESE_SORT, G.MATH, G.ENGLISH

FROM (SELECT * FROM GRADE ORDER BY CHINESE) G

如果对所有科目成绩加上排名序号列呢?

提示一下这回要用到left join了,left join会在下一篇文章中讲解。先看下面sql代码:

SELECT *

FROM (SELECT T.NAME,

T.CHINESE,

T1.CHINESE_SORT AS CHINESE_SORT,

T.MATH,

T2.MATH_SORT    AS MATH_SORT,

T.ENGLISH,

T3.ENGLISH_SORT AS ENGLISH_SORT

FROM GRADE T

LEFT JOIN (SELECT G1.NAME, G1.CHINESE, ROWNUM CHINESE_SORT

FROM (SELECT g.NAME, g.CHINESE

FROM GRADE g

ORDER BY g.CHINESE DESC) G1) T1

ON T1.NAME = T.NAME

LEFT JOIN (SELECT G2.NAME, G2.MATH, ROWNUM MATH_SORT

FROM (SELECT g.NAME, g.MATH

FROM GRADE g

GROUP BY g.NAME, g.MATH

ORDER BY g.MATH DESC) G2) T2

ON T2.NAME = T.NAME

LEFT JOIN (SELECT G3.NAME, G3.ENGLISH, ROWNUM ENGLISH_SORT

FROM (SELECT g.NAME, g.ENGLISH

FROM GRADE g

GROUP BY g.NAME, g.ENGLISH

ORDER BY g.ENGLISH DESC) G3) T3

ON T3.NAME = T.NAME) MyGrade

ORDER BY MyGrade.CHINESE_SORT;

执行代码后结果如下图所示

二、上面的内容主要讲解了ROWNUM的排序,是rownum最基本最直接的用法。不过rownum最常见的用法是用来做分页。

还是那张成绩变:

1、只显示前语文成绩前十名的学生记录

select g.* from grade g where rownum < 10 order by chinese;

很简单有没有。

2、想知道语文成绩第10名以后的学生记录:

select g.* from grade g where rownum > 10 order by chinese;

是这样吗?执行一下,并没有结果。

原因:文章开头说ROWNUM是一个序列,会根据sql语句自动给你加上一列排好顺序的序号列。

rownum总是为满足条件的记录从1开始设序号,所以rownum总是从1开始的。这理解起来并没有问题哈。当从数据库中找到语文成绩第一名的记录时,设序号为1,该记录不满足rownum>10。所以抛弃该记录,接着从数据库中找到语文成绩第二名的记录,又设序号为1,该记录依然不满足rownum>10,依次类推。所以穷尽整张表抛弃了所有记录。

正确的sql应该这样写:

select MyGrade.*

from (select G.*, rownum rn

from (select g.* from grade g order by chinese) G ) MyGrade

where MyGrade.rn >= 10;

先select所有记录并按语文成绩排好序,外套一个select加上序号列。这就为所有记录固定好了排序的顺序。再外套一个select取出从序号>=10 的所有记录;

3、获取第语文成绩有潜力提升到高分阶段的批次记录,比如第6名到第10名的记录:

select MyGrade.*

from (select G.*, rownum rn

from (select g.* from grade g order by chinese) G

where rownum <= 10) MyGrade

where MyGrade.rn >= 6;

当然,下面这段sql也可以实现同样的效果:

select MyGrade.*

from (select G.*, rownum rn

from (select g.* from grade g order by chinese) G

where rownum <= 10) MyGrade

where MyGrade.rn >= 6 and MyGrade.rn <= 10;

不过当数据量很大时,这段代码性能就次了好多,因为它要先遍历所有记录,然后根据序号分页。而对于之前的代码,由于CBO优化模式下,Oracle可以将外层的查询条件推到内层查询中,以提高内层查询的执行效率,所以只是遍历了rownum小于10的记录,就停止了内层查询。所以推荐使用第一种分页方法。

好了,rownum先讲到这里。如果有需要会在之后的文章中补充。下一篇文章讲解inner join、left join和right join的区别和使用。

ORACLE的rownum用法讲解的更多相关文章

  1. ORACLE 中ROWNUM用法总结(转)

    ORACLE 中ROWNUM用法总结! 对于 Oracle 的 rownum 问题,很多资料都说不支持>,>=,=,between...and,只能用以上符号(<.<=.!=) ...

  2. ORACLE 中ROWNUM用法总结!

    ORACLE 中ROWNUM用法总结! 对于 Oracle 的 rownum 问题,很多资料都说不支持>,>=,=,between...and,只能用以上符号(<.<=.!=) ...

  3. 转:ORACLE 中ROWNUM用法总结!

    oracle 分页查询语句:select * from (select u.*,rownum r from (select * from userifno) u where rownum<大值) ...

  4. [转]ORACLE的ProC用法讲解

    pro*c是高级的用法,OCI是oracle的基础用法 如何编译.pc文件: proc code=cpp  parse=none iname=filename.pc oname=filename.cp ...

  5. Oracle中rownum用法警示

    今天调试代码,发现分页查询时使用Oracle中rownum的between......and用法的bug,特此总结: 参考资料:http://blog.csdn.net/lg312200538/art ...

  6. Oracle数据库rownum用法集锦

    Oracle中rownum可以用来限制查询 具体用法: 1.返回查询集合中的第1行 select * from tableName where rownum = 1 2.返回查询集合中的第2行 错误示 ...

  7. [转]ORACLE 中ROWNUM用法总结!

    原文地址:http://www.itpub.net/thread-824147-1-1.html 对于 Oracle 的 rownum 问题,很多资料都说不支持>,>=,=,between ...

  8. ORACLE 中ROWNUM用法总结!(转)

    对于 Oracle 的 rownum 问题,很多资料都说不支持>,>=,=,between...and,只能用以上符号(<.<=.!=),并非说用>,>=,=,be ...

  9. Oracle rownum用法、分页

    转载:ORACLE 中ROWNUM用法总结!  第一部分 1.对于 Oracle 的 rownum 问题,很多资料都说不支持 >, >= , =,  between...and ,只能用 ...

随机推荐

  1. cat <<-EOF >&2

    cat <<-EOF >&2 cat >&2 <==> cat 1>&2 标准输出被重定向到错误输出 默认屏幕 <替换 < ...

  2. 基于SecureCRT的测试环境的克隆的linux/vi相关命令

    #chmod -R 777*; 参数-R:对当前目录下的所有档案与子目录进行相同的权限 变更(即以递归的方式逐个变更). *:通配符,指的是当前目录下的所有文件及目录. 所有文件及其子目录的文件拥有者 ...

  3. 深入理解Word2Vec

    Word2Vec Tutorial - The Skip-Gram Model,Skip-Gram模型的实现原理:http://mccormickml.com/2016/04/19/word2vec- ...

  4. Intellij IDEA搭建vue-cli项目

    1.安装/升级node环境 vue-cli对于node和npm的版本是有要求的.     可以通过 node -v (npm -v)查看当前版本,通过 where node (where npm)查看 ...

  5. Java并发编程73道面试题及答案 —— 面试稳了

    今天主要整理一下 Java 并发编程在面试中的常见问题,希望对需要的读者有用. 1.在java中守护线程和本地线程区别? java中的线程分为两种:守护线程(Daemon)和用户线程(User). 任 ...

  6. bzoj 4585 烟火表演 - 动态规划 - 可并堆

    题目传送门 传送门I 传送门II 题目大意 给定一棵带边权有根树,修改一条边的边权的代价是修改前和修改后的值的绝对值之差.不能将一条边的边权改为负数.问使得根节点到所有叶节点的距离相等的最小代价. 当 ...

  7. bzoj 1420 Discrete Root - 原根 - exgcd - BSGS

    题目传送门 戳我来传送 题目大意 给定$k, p, a$,求$x^{k}\equiv a \pmod{p}$在模$p$意义下的所有根. 考虑模$p$下的某个原根$g$. 那么$x  = g^{ind_ ...

  8. Jbarcode 条形码生成工具

    一.准备jar包 https://sourceforge.net/projects/jbcode/?source=typ_redirect 二.编写工具类 package com.example.de ...

  9. Eclipse查看Servlet源码

    Eclipse查看Servlet源码 @(Java) 1.servlet-api 和 javax.servlet-api的区别 在正式查看Servlet源码前,我们首先要分清楚上述两个jar包的区别. ...

  10. init: wait for '/dev/block/bootdevice/by-name/cache' timed out and took 5007ms【学习笔记】

    平台信息:内核:4.9.112系统:android one平台:qcom sdm439 作者:庄泽彬(欢迎转载,请注明作者) 一.android设备在开机的时候打印了如下的log,由于系统使用了AB分 ...