Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

一对多的主子表场景selectJoinPage分页查询得到的实际数目与total不一致问题 #146

Open
Luyg88 opened this issue Jun 8, 2024 · 5 comments

Comments

@Luyg88
Copy link

Luyg88 commented Jun 8, 2024

当前使用版本(必填,否则不予处理)

1.4.12

该问题是如何引起的?(确定最新版也有问题再提!!!)

使用selectJoinPage分页查询,有leftjoin联表操作,生成查询总数目的sql却没有联表的leftjoin语句,这导致一对多的主子表查询时,查出来的数目和total对不上;比如主表10条数据,每条主表数据有2条子表数据(子表总共20条),这样主表leftjoin子表得到的数据有20条,但是selectJoinPage得到的total是10,这个问题应当怎么处理?有办法让生成的select count(*)也带上leftjoin联表查询吗
image

重现步骤(如果有就写完整)

报错信息

@finalgene
Copy link

finalgene commented Jun 14, 2024

感觉分页一旦遇上了表连接问题很多,多对一的查询可以用,一对多不行, 比如demo中,user连接address查分页,按照user的 id 正序排, 此时虽然分页大小设置的10, 却只查到两个user, 因为其余的address 信息聚合到了 user的 list中去了

@Test
        void testJoin() {
                MPJLambdaWrapper<UserDO> wrapper = new MPJLambdaWrapper<UserDO>()
                                .selectAll(UserDO.class)
                                .selectCollection(AddressDO.class, UserDTO::getAddressList)
                                .leftJoin(AddressDO.class, AddressDO::getUserId, UserDO::getId)
                                .orderByAsc(UserDO::getId);

 
                Page<UserDTO> page = userMapper.selectJoinPage(new Page<>(1, 10), UserDTO.class, wrapper);
              
        }

@1025946443
Copy link

看网上有说是因为id重复而触发了mybatis去重,需要设置伪列?不知道是不是这个问题.
但是我这也遇到该问题了,查到100条但是实际list只有2条,我想去增加伪列的时候,却不知道通过Lambda如何实现增加

@qq61966100
Copy link

@Luyg88 怎么解决了呢?

@liuyuanting1209
Copy link

#157

@wangjiancheng180
Copy link

感觉分页一旦遇上了表连接问题很多,多对一的查询可以用,一对多不行, 比如demo中,user连接address查分页,按照user的 id 正序排, 此时虽然分页大小设置的10, 却只查到两个user, 因为其余的address 信息聚合到了 user的 list中去了

@Test
        void testJoin() {
                MPJLambdaWrapper<UserDO> wrapper = new MPJLambdaWrapper<UserDO>()
                                .selectAll(UserDO.class)
                                .selectCollection(AddressDO.class, UserDTO::getAddressList)
                                .leftJoin(AddressDO.class, AddressDO::getUserId, UserDO::getId)
                                .orderByAsc(UserDO::getId);

 
                Page<UserDTO> page = userMapper.selectJoinPage(new Page<>(1, 10), UserDTO.class, wrapper);
              
        }

本质是所谓的分页就是在sql后面拼接limit和offset,所以一对多的情况下,主表中的10条数据每条对应了n条关联表的数据,join后数据库sql执行完后就是有n*10条数据,你分页10条数据sql语句imit 10,把结果集的前10条数据封装到实体类中后,实际可能只拿了主表的5条数据与预期不符,所以可以走两边查询,第一遍只查询主表的主键用distinct去重查得到正确的条数和主表的主键,再关联查询一遍用刚刚分页查出来的·的主键列表过滤,得到结果集就是预期的分页结果集

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants