oracle用rownum分页的问题
select * from
(select seq, rownum rm from table_a where biz_date = '2023-02-03' order by id) a
where
a.rm <= pageNum * pageSize
and
a.rm > (pageNum-1) * pageSize
分页sql是这样写的,运行了几个月没有出问题,最近突然出现问题,导致有的数据被查到了好几次,后来改成了标准写法就好了,但是还是没有理解到是什么原因,有没有小伙伴帮忙指明一个方向
修改后写法
select * from
(select
a.*, rownum rm
from
(select req from table_a where biz_date = '2023-02-03' order by id) a
where
rownum <= pageNum * pageSize)
where
rm > (pageNum-1) * pageSize
该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
您提供的 Oracle 分页 SQL 语句使用了子查询和 rownum
来分页。虽然这种方法在某些情况下可以工作,但是在某些情况下可能会产生错误的结果,原因如下:
rownum
是 Oracle 中的伪列,它仅在查询结果返回给客户端之前才会分配值。因此,在子查询内部使用 rownum
进行排序和过滤时,可能会导致结果不正确。
在外层查询中使用 rownum
进行过滤时,可能会导致查询结果不完整。这是因为 rownum
是在查询结果返回给客户端之前进行计算的,所以在结果集中的前几行可能会被过滤掉。
为了解决这些问题,通常建议使用 Oracle 提供的标准分页方法,即使用 ROW_NUMBER()
函数和子查询来分页。以下是示例代码:
SELECT *
FROM (
SELECT a.*, ROW_NUMBER() OVER (ORDER BY id) AS rn
FROM table_a a
WHERE a.biz_date = '2023-02-03'
)
WHERE rn BETWEEN ((pageNum-1) * pageSize + 1) AND (pageNum * pageSize)
在这个例子中,我们首先在子查询中使用 ROW_NUMBER()
函数来给每个行分配一个行号,然后在外层查询中使用 BETWEEN
运算符和行号来进行分页。
请注意,使用 ROW_NUMBER()
函数和子查询的方法可以处理排序和过滤操作,因此可以更灵活地进行分页。此外,这种方法通常比 rownum
方法更快,因为它可以分配行号而不需要在每一行上执行过滤操作。
如果以上回答对您有所帮助,点击一下采纳该答案~谢谢
需求:对T_ACCOUNT表的usenum字段进行排序,返回连续的排名,无论值是否相等
语句:
select row_number() over(order by usenum desc),usenum from T_ACCOUNT;
结果:
用row_number()分析函数实现的分页查询相对三层嵌套子查询要简单的多:
select * from
(select row_number() over(order by usenum desc )
rownumber,usenum from T_ACCOUNT)
where rownumber>10 and rownumber<=20;
查询结果如下: