select * from ( select rownum rnum,a.* from (my_query) a where rownum <= 30 ) where rnum > 15;
现在我需要运行一个单独的sql语句来对“my_query”执行“select count”,以获取my_query的总结果数(以便我可以将它显示给用户并使用它来计算出总页数等).
有没有办法通过第二个查询,即从上面的查询获取结果的总数,而不是这样做?我已经尝试添加“max(rownum)”,但它似乎不起作用(我收到一个错误[ORA-01747],似乎表明它不像我在组中的关键字rownum).
我想要从原始查询获取这个原理而不是在单独的sql语句中执行的理由是“my_query”是一个昂贵的查询,所以我宁愿不运行它两次(一次获得计数,一次获得数据页)如果我没有;但是无论如何,如果可能的话,如果有任何额外的开销,我可以想出从单个查询中获取结果的数量(同时获取我需要的数据页面).请指教.
这正是我想要做的,因为我收到一个ORA-01747错误,因为我相信它不像我在组中有ROWNUM.注意,如果有另外一个解决方案不使用max(ROWNUM),但是别的东西,这也是非常好的.这个解决方案是我第一个想到可能会起作用的.
SELECT * FROM (SELECT r.*,ROWNUM RNUM,max(ROWNUM) FROM (SELECT t0.ABC_SEQ_ID AS c0,t0.FIRST_NAME,t0.LAST_NAME,t1.score FROM ABC t0,XYZ t1 WHERE (t0.XYZ_ID = 751) AND t0.XYZ_ID = t1.XYZ_ID ORDER BY t0.RANK ASC) r WHERE ROWNUM <= 30 GROUP BY r.*,ROWNUM) WHERE RNUM > 15
———编辑——–
请注意,根据第一个评论,我尝试了以下似乎有效的内容.我不知道它的表现与其他解决方案的效果(我正在寻找解决方案,以满足我的需求,但表现最好).例如,当我运行它需要16秒.当我拿出COUNT(*)OVER()RESULT_COUNT时,只需要7秒钟:
SELECT * FROM (SELECT r.*,) FROM (SELECT COUNT(*) OVER () RESULT_COUNT,t0.ABC_SEQ_ID AS c0,t1.score FROM ABC t0,XYZ t1 WHERE (t0.XYZ_ID = 751) AND t0.XYZ_ID = t1.XYZ_ID ORDER BY t0.RANK ASC) r WHERE ROWNUM <= 30) WHERE RNUM > 1
解释计划从进行排序(ORDER BY STOP KEY)改变为执行WINDOW(排序).
之前:
SELECT STATEMENT () COUNT (STOPKEY) VIEW () SORT (ORDER BY STOPKEY) NESTED LOOPS () TABLE ACCESS (BY INDEX ROWID) XYZ INDEX (UNIQUE SCAN) XYZ_ID TABLE ACCESS (FULL) ABC
后:
SELECT STATEMENT () COUNT (STOPKEY) VIEW () WINDOW (SORT) NESTED LOOPS () TABLE ACCESS (BY INDEX ROWID) XYZ INDEX (UNIQUE SCAN) XYZ_ID TABLE ACCESS (FULL) ABC
解决方法
SELECT * FROM (SELECT r.*,COUNT(*) OVER () RESULT_COUNT FROM (SELECT t0.ABC_SEQ_ID AS c0,t1.score FROM ABC t0,XYZ t1 WHERE (t0.XYZ_ID = 751) AND t0.XYZ_ID = t1.XYZ_ID ORDER BY t0.RANK ASC) R) WHERE RNUM between 1 and 15
原因是在WHERE子句之后对COUNT(*)OVER()窗口函数进行求值,因此不会给出记录的总计数,而是记录满足ROWNUM< = 30条件的计数. 如果您不能接受此查询的性能,或执行2个单独的查询,或许您应该考虑一个解决方案,例如FrustratedWithFormsDesigner在其关于缓存记录计数的注释中提出的解决方案. 如果您定期使用数据库,我建议您获得SQL Cookbook的副本.它是一本非常有用的提示的特别书.