分页从-1开始读取数据只会重复一条记录
2014-04-18 19:14
323 查看
今天做项目的时候发现一个小Bug,引得自己一番思考,在项目中有一个简历信息列表的分页问题,第一页的最后一条信息和第二页的第一条信息是重复的,但是从第二页以后就没有重复的信息了(这个是后来才发现的),就此问题我进行了一番研究,研究结果发现是因为作者在数据访问层对业务逻辑层传递过来的分页起始值再减了一个1,导致第一页的时候sql语句分页的起始值是-1,代码如下:
业务逻辑层相关代码: ResumeDal.ResumesList((page - 1) * showCount, showCount * page); 参数说明:(参数1:分页开始值,参数2:分页结束值)
数据访问层相关代码: int start-=1;(分页开始值)
Sql语句:
select * from [Resume] where [ID] in
(
select top 30 [ID] from
(
select r.ID,row_number()over(order by r.[UpdateTime] desc) as r
from [Resume] r
inner join [User] u on r.UserID = u.ID
left join [Area] c on r.AreaId=c.ID
left join [Subject] s on r.SubId=s.ID
where u.[IsCompany]=0
) as t
where t.r>-1
)
看到这里,我马上想到的就是每次分页都会对起始位置的值进行减1操作,那么不是每页都会有一条重复的数据吗?那么不就有很多的真实数据会看不见吗?(因为页数是根据信息总数除以每页显示的条数得到的,信息总数是真实数据的条数)经过反复测试,我发现只有第一页的最后一条数据和第二页的第一条数据是重复的,从第二页以后的数据就没有重复的了,测试结果与我的第一想法完全不一致,这令我陷入了迷茫当中,为了消除这个疑惑,我静下心来反复测试,终于得到了正解。
原理是这样的,获取第一页数据的时候,分页的起始值为-1,作者使用的是row_number进行分页,每页显示的条数固定不变为30,所以实际的取值范围为1-30,这样才满足top 30,当获取第二页的数据时,分页的起始值就变成了29,由于t.r要大于分页开始值,所以实际的取值范围为30-59,观察红色部分可以知道,因为第一页的分页起始值为-1和top 30的原因,导致数据库在获取第一页的数据时取到了原本应该是属于第二页的数据,所以出现了"第一页的最后一条数据和第二页的第一条数据是重复的"这样一种现象,当获取第三页数据时,分页的起始值为59,同理实际的取值范围为60-89,第三页的数据就没有重复了,同样的道理,后面的数据也不会有重复的,所以才会出现"只有第一页的最后一条数据和第二页的第一条数据是重复的,从第二页以后的数据就没有重复的了"这样一种情况,好了,到此已经水落石出了,虽然只是一个小小的问题,却也能让人一番思考,希望自己以后写代码能够想得更多,收获更多。
感谢您怀着耐心看完整篇博文!!!
如果文章有什么错误或不当之处,请您斧正!
您有任何意见或者建议,您可以给我发邮件,也可以在下面留言,我看到了会第一时间回复您的,谢谢!
业务逻辑层相关代码: ResumeDal.ResumesList((page - 1) * showCount, showCount * page); 参数说明:(参数1:分页开始值,参数2:分页结束值)
数据访问层相关代码: int start-=1;(分页开始值)
Sql语句:
select * from [Resume] where [ID] in
(
select top 30 [ID] from
(
select r.ID,row_number()over(order by r.[UpdateTime] desc) as r
from [Resume] r
inner join [User] u on r.UserID = u.ID
left join [Area] c on r.AreaId=c.ID
left join [Subject] s on r.SubId=s.ID
where u.[IsCompany]=0
) as t
where t.r>-1
)
看到这里,我马上想到的就是每次分页都会对起始位置的值进行减1操作,那么不是每页都会有一条重复的数据吗?那么不就有很多的真实数据会看不见吗?(因为页数是根据信息总数除以每页显示的条数得到的,信息总数是真实数据的条数)经过反复测试,我发现只有第一页的最后一条数据和第二页的第一条数据是重复的,从第二页以后的数据就没有重复的了,测试结果与我的第一想法完全不一致,这令我陷入了迷茫当中,为了消除这个疑惑,我静下心来反复测试,终于得到了正解。
当前页 分页开始值 分页结束值 实际获取数据的范围 每页显示的条数 1 -1 30 1-30 30 2 29 59 30-59 30 3 59 89 60-89 30 4 89 119 90-119 30 5 119 149 120-149 30
原理是这样的,获取第一页数据的时候,分页的起始值为-1,作者使用的是row_number进行分页,每页显示的条数固定不变为30,所以实际的取值范围为1-30,这样才满足top 30,当获取第二页的数据时,分页的起始值就变成了29,由于t.r要大于分页开始值,所以实际的取值范围为30-59,观察红色部分可以知道,因为第一页的分页起始值为-1和top 30的原因,导致数据库在获取第一页的数据时取到了原本应该是属于第二页的数据,所以出现了"第一页的最后一条数据和第二页的第一条数据是重复的"这样一种现象,当获取第三页数据时,分页的起始值为59,同理实际的取值范围为60-89,第三页的数据就没有重复了,同样的道理,后面的数据也不会有重复的,所以才会出现"只有第一页的最后一条数据和第二页的第一条数据是重复的,从第二页以后的数据就没有重复的了"这样一种情况,好了,到此已经水落石出了,虽然只是一个小小的问题,却也能让人一番思考,希望自己以后写代码能够想得更多,收获更多。
感谢您怀着耐心看完整篇博文!!!
如果文章有什么错误或不当之处,请您斧正!
您有任何意见或者建议,您可以给我发邮件,也可以在下面留言,我看到了会第一时间回复您的,谢谢!
相关文章推荐
- 分页从-1开始读取数据只会重复一条记录
- SQL删除重复记录,只保留一条数据。
- Oracle删除重复记录只保留一条数据的几种方法
- 对于分页时,若数据库的数据不断更新,不让前台显示脏数据(同一条数据重复显示)的处理方式
- Oracle查询重复数据并删除,只保留一条记录
- Oracle查询重复数据并删除,只保留一条记录
- 笔记:Oracle查询重复数据并删除,只保留一条记录
- 转载:如何写个SQL语句查询一个字段里是否有重复记录如果有只读取其中一条记录
- 删除oracle 表中重复数据sql语句、保留rowid最小的一条记录
- Oracle查询重复数据并删除,只保留一条记录
- Oracle查询一批数据,某字段的内容有重复数据,怎样取相同的记录中时间最近的一条
- sql重复数据只取一条记录
- Oracle删除重复记录只保留一条数据的几种方法
- Oracle查询重复记录,分页和去掉重复数据的查询语句
- Yii2-使用ActiveRecord数据操作数据分页的记录重复问题
- Oracle查询重复记录,分页和去掉重复数据的查询语句
- Oracle删除重复记录只保留一条数据的几种方法
- 使用hibernate对oracle数据库中数据分页出现重复记录
- SQL删除数据表中重复记录中的一条
- 分页读取数据记录(row_number()函数)