[转]oracle分页用两层循环还是三层循环?
select t2.* from --两层嵌套
(select t.* , rownum as row_numfrom t where rownum <=20) t2
where t2.row_num > 11
select t3.* from ( --三层嵌套
select t2.*, rownum as row_num from (
select * from t
) t2 where rownum<=20
) t3
where t2.row_num>11
两层嵌套 ==三层嵌套???
select t2.* from (
select t.*, rownum as row_num from t where rownum<=20 order by ID asc
) t2 where t2.row_num>10 order by ID asc
因为在查询的时候,order by 的执行是在 select 之后的,所以在第一层查询中,得到的结果可能是如下
ID row_num
1 3
8 20
20 4
21 1
...
100 8
===20条记录,其中row_num字段的值在1-20
这样的子结果集,在经过第二层过滤的时候,是得不到我们想要的结果的
ID
11
12
13
...
20
所以需要用如下的sql语句实现分页排序
select t3.* from (
select t2.*, rownum as row_num from (
select * from t order by t.id asc
) t2 where rownum<=20
) t3
where t2.row_num>11
order by t3.id asc
为什么基于ROWNUM的oracle分页实现,要采用三层嵌套的方式?
1 首先,在没有order by clause的情况下,oracle的查询结果的顺序会是不确定的。如上面的例子。所以order by的使用是应该的,以免因为index等的原因导致不确定的results order。
2 其次,在order by 和 ROWNUM同时使用时,oracle默认的策略是先为伪列rownum赋值,再order by。
引用
rownum与order by同时存在的问题
当 where 后面有rownum的判断,并且存在order by时候,rownum的优先级高!
oracle会先执行rownum的判断,然后从结果中order by,很明显是错误的结果啦!就好像学校要取成绩最好的前10名同学,结果这种方法一执行,成了取出10名同学,然后按照成绩的高低排序!
这点与SQL Server的TOP完全不同,TOP遇上order by,是先执行order by,在分页的;
解决办法就是先执行order by,然后嵌套执行rownum-----说白啦就是用()改变函数的优先级! 所以,第二层嵌套的目的就是:让结果先order by,再取rownum!
3 再次,因为rownum不可使用 >(=) 来判断的原因,所以需要最外围的第三层嵌套
SELECT *
FROM (SELECT *
FROM (SELECT ROWNUM AS ROW_ID, ORDER_ID
FROM ORDERS
ORDER BY ORDER_ID DESC) A
WHERE ROW_ID < 10)
WHERE ROW_ID >= 5; --上面这样写也是错误的,正如前面的原因,有order by 和rownum时,先给rownum赋值,然后再对结果进行order by,
所以上面的语句同样是取rownum为5--10之间的记录,而不是排好序之后的5--10记录。
正确写法:
SELECT B.ORDER_ID,B.ORDER_DETAILS,B.R_ID
FROM (SELECT A.ORDER_ID,A.ORDER_DETAILS,ROWNUM AS R_ID --对排序好的结果取其rownum,再取rownum 小于给定值的记录(不能直接对rownum取大于)
FROM (SELECT ORDER_ID,ORDER_DETAILS --获取排序好的结果集
FROM ORDERS
ORDER BY ORDER_ID DESC) A
WHERE ROWNUM < 10) B
WHERE R_ID >= 5; --取R_ID大于给定值的记录
PS: 不能在where语句中使用别名进行过滤(汗一个,看来很多东西需要实践啊。)
http://www.cnblogs.com/binblog/archive/2012/01/02/2309991.html
http://www.xuebuyuan.com/1292664.html
[转]oracle分页用两层循环还是三层循环?的更多相关文章
- Oracle 分页 ROWNUM 两种分页方法和ROWID用法
一 原因一 oracle默认为每个表生成rowmun,rowid字段,这些字段我们称之为伪列 测试表 CREATE TABLE A ( AID NUMBER() primary key, ANAME ...
- oracle 分页的两种方式
实例:查询5-8名学生的姓名与成绩 --oracle的分页1 between 方式(分三次查询,第一次只作排序,第二次给表加上rownum序列,第三次为查询结果) select s.scorenumb ...
- java中怎么跳出两层for循环
使用标号(使用标号跳出两层或者多层for循环): outterLoop: for (int i = 0; i < 9; i++){ for (int j = 0; j & ...
- Oracle分页查询与RowNum
1. RowNum伪列 Oracle中,RowNum是一个伪列,表示当前记录是查询结果集中的第几条. RowNum在使用上应该注意,不能在where条件中用RowNum大于.大于等于.等于某个大于1的 ...
- Oracle 分页原理
oracle rownum 及分页处理的使用方法 在实际应用中我们经常碰到这样的问题,比如一张表比较大,我们只要其中的查看其中的前几条数据,或者对分页处理数据.在这些情况下我们都需要用到rownum. ...
- mysql和oracle 分页查询(转)
最近简单的对oracle,mysql,sqlserver2005的数据分页查询作了研究,把各自的查询的语句贴出来供大家学习..... (一). mysql的分页查询 mysql的分页查询是最简单的,借 ...
- Oracle分页查询语句的写法(转)
Oracle分页查询语句的写法(转) 分页查询是我们在使用数据库系统时经常要使用到的,下文对Oracle数据库系统中的分页查询语句作了详细的介绍,供您参考. Oracle分页查询语句使我们最常用的 ...
- 关于oracle分页的一些想法
今天突然回想起oracle的分页查询,大部分情况大家都是用: SELECT * FROM (SELECT A.*, ROWNUM RN FROM (SELECT * FROM TABLE_NAME) ...
- [Oracle]关于Oracle分页写法的性能分析及ROWNUM说明
关于分页写法的性能分析及ROWNUM的补充说明 分页写法 一.测试前数据准备 SQL> SELECT COUNT(*) FROM BPM_PROCVAR; COUNT(*) ---------- ...
随机推荐
- PostgreSQL安装和创建用户和创建数据库
一.安装 可以参考postgresql官网安装教程:https://www.postgresql.org/download/linux/redhat/ Centos 6 安装postgresql 10 ...
- Alpha 冲刺 (4/10)
目录 摘要 团队部分 个人部分 摘要 队名:小白吃 组长博客:hjj 作业博客:冲刺4 团队部分 后敬甲 过去两天完成了哪些任务 文字描述 主页部分图标的替换 -拍照按钮的设计和测试 GitHub代码 ...
- 020_nginx禁止ip默认参数是$remote_addr无法禁止真实ip的问题
由于网站使用了cdn所以$remote_addr获取的ip是cdn的ip,我现在先禁止某些ip访问发现无法禁止cdn传递过来的客户端的ip也就是$http_x_forwarded_for这个参数.比如 ...
- Find Lines
(Uva 6955可以直接随机,湖大OJ 13348 要优化) 题意:给出 n个点的坐标, 一个 百分数p, 求是否有一条直线上有 n * p /100个点… 随机化算法,但也要优化下……(TLE, ...
- 前端 -----jQuery的位置信息
08-jQuery的位置信息 jQuery的位置信息跟JS的client系列.offset系列.scroll系列封装好的一些简便api. 一.宽度和高度 获取宽度 .width() 描述:为匹配的 ...
- Laravel资源理由器跟隐式控制的对比及是怎样的吧?- Route::resource vs Route::controller
stackoverflow找到的问题:http://stackoverflow.com/questions/23505875/laravel-routeresource-vs-routecontrol ...
- Laravel 5.2数据库--迁移migration
Laravel中的migrations文件存放的是数据库表文件等结构,可以说是一个跟git差不多的,可以说像是数据库的版本控制器,所以可以叫做迁移.因为它可以很快速的很容易地构建应用的数据库表结构. ...
- 关于如何实现Android透明状态栏的总结
开门见山. 原来做的效果,如下图(顶部有一条明显的橙色状态栏): a1.gif 改过之后(顶部状态栏是透明的): p2.gif 我发现网上写的一些文章,不够简洁明了,我整理了一下,复制粘贴一下 ...
- Confluence 6 通过 SSL 或 HTTPS 运行 - 重定向所有的 URLS 到 HTTPS 的安全考虑
尽管现在 HTTPS 现在已经激活并且可用了.老的 HTTP URLs (http://localhost:8090)还是可以访问的.现在你需要重定向所有 URLs 到他们的 HTTPS 链接中.你可 ...
- Redis事务概念
redis事务与监控 Author:SimpleWu GitHub-redis 在redis中它的事务与批处理非常相似 Redis中的事务(transaction)是一组命令的集合.事务同命令一样都是 ...