微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

sql – (Oracle)使用分页查询时如何获取总结果?

我正在使用Oracle 10g和以下范例来获取一段时间的15个结果页面(这样当用户查看搜索结果的第2页时,他们会看到记录16-30).
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的副本.它是一本非常有用的提示的特别书.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐