前些天出现了一个非常有意思的问题,sql简单化出来以后是下面这个样:
select * from(
SELECT tmp_page.*,
rownum row_id FROM (
SELECT * FROM T_BAP_MEC_TZERO_STL ORDER BY dt_ute desc nulls last
)tmp_page WHERE rownum<10
)where row_id>0
出现的问题是前面几页的数据几乎一样
那么为什么会导致这样的问题出现呢?
为了重现问题我重现建立了一张表方便缩小研究范围,排除非影响因素
create table ttt1 (a varchar2(3),b number);
insert into ttt1 values('a',1);
insert into ttt1 values('b',1);
insert into ttt1 values('c',1);
insert into ttt1 values('d',1);
insert into ttt1 values('e',1);
insert into ttt1 values('f',1);
insert into ttt1 values('g',1);
insert into ttt1 values('h',1);
insert into ttt1 values('i',1);
insert into ttt1 values('j',1);
insert into ttt1 values('k',1);
insert into ttt1 values('l',2);
insert into ttt1 values('m',3);
insert into ttt1 values('m1',3);
insert into ttt1 values('m2',3);
insert into ttt1 values('m3',3);
insert into ttt1 values('m4',3);
insert into ttt1 values('m5',3);
insert into ttt1 values('m6',3);
insert into ttt1 values('m7',3);
insert into ttt1 values('m8',3);
insert into ttt1 values('m9',3);
insert into ttt1 values('m10',3);
insert into ttt1 values('m11',3);
insert into ttt1 values('m12',3);
insert into ttt1 values('m13',3);
insert into ttt1 values('n',null);
insert into ttt1 values('o',null);
insert into ttt1 values('p',null);
insert into ttt1 values('k',null);
insert into ttt1 values('r',null);
insert into ttt1 values('s',null);
insert into ttt1 values('t',null);
insert into ttt1 values('u',null);
insert into ttt1 values('v',null);
insert into ttt1 values('w',null);
SELECT tmp_page.*, ROWID FROM ( SELECT * FROM ttt1 order by b desc )tmp_page WHERE rownum<=5
![]()
SELECT tmp_page.*, ROWID FROM ( SELECT * FROM ttt1 order by b desc )tmp_page WHERE rownum<=10
![]()
select * from( SELECT tmp_page.*, ROWID FROM ( SELECT * FROM ttt1 order by b desc )tmp_page WHERE rownum<=5 )where row_id>0;
![]()
select * from( SELECT tmp_page.*, rownum row_id FROM ( SELECT * FROM ttt1 order by b desc )tmp_page WHERE rownum<=10 )where row_id>5;
![]()
1.这样你就能缩小答案范围在rownum取值这里,因为第一次取记录数5条的时候,k在第5位,而第二次k排在了第6位,所以第一页和第二页都出现了k记录。
2.在转换一下:
当你order by 不能保证唯一性的时候,rownum是怎么去选择前5条记录的呢?为什么不是
SELECT a,b,rowid FROM ttt1 order by b desc
的前5条记录呢?那么到底是rownum还是order by 导致的最终问题呢?
如果是升序的还好,他会根据物理存放顺序来取数据,但是倒序的话很明显变成的随机性,这里假设