问题
一个主表table_master, 对应三个子表 table_a, table_b, table_c,主子是一对多的关系
查询的接口需要主子结构的数据,而且要满足主表和子表的查询条件,并且还要支持分页
select
tm.*,
ta.*,
tb.*,
tc.*
from table_master tm
left join table_a ta on tm.id = ta.pid
left join table_b tb on tm.id = tb.pid
left join table_c tc on tm.id = tc.pid
where
//主表查询条件
//a表查询条件
//b表查询条件
//c表查询条件
limit 20, 0 // size: 20 current:1
如果这样写SQL,子表有多条分页就会出现问题
//查询结果
master_id a_id b_id c_id
1 1 1 1
1 1 2 1
1 1 2 2
2 3 3 3
total = 4
//但实际我们需要的数据是这样的
master_id List<a> List<b> List<c>
1 [1] [1,2] [1,2]
2 [3] [3] [3]
total = 2
SQL中查询出来的结果有四条,主子结构组装后只有两条;因为分页是在SQL层进行的,分页数据就会不正确
解决方案
因为分页和查询条件都要满足,一次查询似乎无法完成需求,那么就查询两次。
第一次查询的时候,将查询条件和分页都带上,但只查询主表ID,因为查询结果是主子结构根据主表来分页的
第二次查询的时候不带分页,把第一次查询的主表ID作为查询条件,主子表的查询条件也要带上
分页信息取第一次的结果,数值取第二次的结果,就能完成正确的分页查询
//第一次查询
select
distinct
tm.id
from table_master tm
left join table_a ta on tm.id = ta.pid
left join table_b tb on tm.id = tb.pid
left join table_c tc on tm.id = tc.pid
where
//主表查询条件
//a表查询条件
//b表查询条件
//c表查询条件
limit 20, 0 // size: 20 current:1//第二次查询
select
tm.*,
ta.*,
tb.*,
tc.*
from table_master tm
left join table_a ta on tm.id = ta.pid
left join table_b tb on tm.id = tb.pid
left join table_c tc on tm.id = tc.pid
where
tm.id in (第一次查询的主表ID)
//主表查询条件
//a表查询条件
//b表查询条件
//c表查询条件