背景
pg单字段排序,排序字段中可能会出现重复,这样就会导致我们在进行分页查询时会出现一些和预期不相符的现象,如这个数据在第一页出现了,然后再第二页又出现。
复现步骤
create table test_select_order_page_duplicate ( id varchar(36) not null constraint test_select_order_page_duplicate_pk primary key, name varchar, age integer ); alter table test_select_order_page_duplicate owner to postgres; insert into test_select_order_page_duplicate ( id, name, age ) values ( '1111', 'aa', 12 ), ( '2222', 'aa', 12 ), ( '3333', 'aa', 12 ), ( '4444', 'aa', 12 ), ( '5555', 'aa', 13 ), ( '6666', 'aa', 12 ), ( '7777', 'aa', 12 ), ( '8888', 'aa', 13 ), ( '9999', 'aa', 12 ), ( '10101010', 'aa', 12 ), ( '11111111', 'aa', 14 ), ( '12121212', 'aa', 14 ), ( '13131313', 'aa', 12 );
查询第一页
select * from test_select_order_page_duplicate tsopd order by tsopd.age limit 3;
id | name | age |
2222 | aa | 12 |
3333 | aa | 12 |
1111 | aa | 12 |
查询第二页
select * from test_select_order_page_duplicate tsopd order by tsopd.age limit 3 offset 3;
id | name | age |
2222 | aa | 12 |
6666 | aa | 12 |
7777 | aa | 12 |
可以明显看到,两次分页查询出现了同一条id为2222的记录,但实际上数据库里只有一条2222,查询结果莫名出现了重复数据。
解决方式
核心思路就是让order by拥有唯一性。
具体解决方式就是,补充一个有唯一约束或者大概率唯一的字段作为次级排序条件。
例如,补充主键作为排序条件:
select * from test_select_order_page_duplicate tsopd order by tsopd.age, tsopd.id desc
预防
n对1关系的连表查询时,如果根据1端表的字段排序就肯定要加一个n端的id
本篇文章如有帮助到您,请给「翎野君」点个赞,感谢您的支持。