oracle分页查询数据重复问题、分页排序陷阱
2013-05-22 17:42
921 查看
select * from (select rownum as rn, ab.* from (SELECT t.id, e.ehr_id, nh_code, name, sex, id_card, (to_number(to_char(sysdate, 'yyyy')) - to_number(to_char(birthday, 'yyyy'))) age,home_address, telephone, t.enable_flag, t.create_user, t.create_date, t.modify_date, village_id, (SELECT answer FROM ehr_s_person_answer WHERE ehr_id = e.ehr_id AND question_id = 546) lxrdh, (SELECT count(1) FROM ehr_examination_record WHERE ehr_id = e.ehr_id AND enable_flag = 1) exam_count, (SELECT count(1) FROM ehr_ht_manage_visit_record WHERE ehr_id = e.ehr_id AND enable_flag = 1) visit_count FROM ehr_info e JOIN ehr_hypertension t ON e.ehr_id = t.ehr_id AND t.enable_flag != 3 WHERE e.region_id IN (23) AND e.hosp_id = 1 order by sex desc) ab where rownum <= 50) abc where rn > 40
以上分页查出来的数据可能会引起分页数据重复的现象
原因:
1.因为oracle是按块进行读取数据的,如果数据按顺序存储,则可能使读取出来的数据是按顺序的,给用户误解为默认排序。事实上,oracle没有进行任何排序操作,如果sql没有要求排序,oracle会顺序的从数据块中读取符合条件的数据返回到客户端。所以在没有使用排序sql的时候,分页返回的数据可能是按顺序的,也可能是杂乱无章的,这都取决与数据的存储位置。在oracle分页查询过程中,如果数据的物理位置发生了改变,就可能会引起分页数据重复的现象。
2.对于以上SQL脚本,优化器采用了“SORT (ORDER BY STOPKEY)”。“SORT (ORDER BY STOPKEY)”不需要对所有数据进行排序,而是只要找出结果集中的按特定顺序的最前N条记录,一旦找出了这N条记录,就无需再对剩下的数据进行排序,而直接返回结果。这种算法我们可以视为是“快速排序”算法的变种。快速排序算法的基本思想是:先将数据分2组集合,保证第一集合中的每个数据都大于第二个集合中每个数据,然后再按这个原则对每个集合进行递归分组,直到集合的单位最小。在进行“SORT
(ORDER BY STOPKEY)”时,首先找出N条数据(这些数据并没有做排序)放在第一组,保证第一组的数据都大于第二组的数据,然后只对第一组数据进行递归。可以看到,基于这样的算法基础上,如果N的数值不同,数据的分组也不同(如N=20时,第一次分组比例为12:8,然后继续递归;当N=10时,第一次分组比例为3:7 … …),这样,在数据的排序字段值都相等时,输出结果的顺序就会因为N值不同而不同。
解决方法:
select * from (select ab.*,rownum as rn from (SELECT id, e.ehr_id, nh_code, name, sex, id_card, to_number(to_char(sysdate, 'yyyy')) - to_number(to_char(e.birthday, 'yyyy')) age, home_address, telephone, t.enable_flag, t.create_user, t.create_date, t.modify_date, village_id, (SELECT answer FROM ehr_s_person_answer WHERE ehr_id = e.ehr_id AND question_id = 546) lxrdh, (SELECT count(1) FROM ehr_examination_record WHERE ehr_id = e.ehr_id AND enable_flag = 1) exam_count, (SELECT count(1) FROM ehr_diabetesMgvisitrecord WHERE ehr_id = e.ehr_id AND enable_flag = 1) visit_count FROM ehr_info e JOIN ehr_diabetes t ON e.ehr_id = t.ehr_id WHERE t.enable_flag != 3 AND e.region_id IN (23) AND e.hosp_id = 1 order by sex desc,id ) ab) abc where rn <= 10 and rn > 1后记:
1.后面的方法相对来说对数据库的性能会有一些影响
2.要正确使用oracle分页查询,sql语句中必须有排序条件。
3.排序条件如果没有唯一性,那么必须在后边跟上一个唯一性的条件,比如主键
解决方法必须满足以上2、3方法!!!!!!!!!!!!
参考:http://database.51cto.com/art/201010/231533.htm
/article/1490542.html
相关文章推荐
- Oracle分页查询排序数据重复问题
- oracle分页查询数据重复问题的解决
- SQL分页排序的实现与分页数据重复问题——以Oracle rownum为例
- SQL分页排序的实现与分页数据重复问题——以Oracle rownum为例
- oracle 分页查询数据重复问题
- 如何解决oracle分页查询数据重复问题
- SQL分页排序的实现与分页数据重复问题——以Oracle rownum为例
- oracle分页查询数据重复问题
- oracle分页查询数据重复问题的解决
- SQL分页排序的实现与分页数据重复问题——以Oracle rownum为例
- oracle分页查询数据重复问题的解决
- oracle分页查询数据重复问题
- oracle分页查询数据重复问题
- 教您如何解决oracle分页查询数据重复问题
- Mybatis oracle多表联合查询分页数据重复的问题
- mysql排序不稳定,分页查询数据有重复和遗漏
- Oracle分页查询中排序与效率问题
- mysql 5.6 order by limit 排序分页数据重复问题
- oracle排序,出现页数不同数据却重复问题的原因及解决办法
- 数据库分页时order by排序不唯一,分页出现重复数据问题