Jooq LeftJoin查询异常:预期返回两条模板记录仅得一条
LEFT JOIN 变内连接?问题出在这个细节!
你是不是纳闷,明明写了LEFT JOIN,结果只返回了关联上task的那条模板记录,没关联的那条直接消失了,跟用了INNER JOIN一样?别着急,我帮你捋捋问题出在哪。
问题根源:WHERE子句的过滤逻辑干扰了LEFT JOIN
当你用LEFT JOIN时,没有对应task的模板记录,TASK表的所有字段都会是NULL。但你在WHERE里加了针对TASK的三个条件:
TASK.ENTITY_NAME.eq(entityName)TASK.ENTITY_ID.eq(entityId)TASK.DELETED.eq(Boolean.FALSE)
NULL和任何值做比较结果都是不成立的,所以这些没有关联task的记录直接被WHERE条件过滤掉了,自然就只剩关联上的那条,看起来像内连接。
解决办法:把TASK的过滤条件移到JOIN的ON子句里
LEFT JOIN的ON子句是用来控制关联逻辑的,把TASK的条件放在这里,只会筛选出符合条件的task记录去关联模板,不会过滤掉本身没有task的模板记录。修改后的代码如下:
var query = dsl.select(TASK_TEMPLATE.fields()) .select(TASK.fields()) .from(TASK_TEMPLATE) .leftJoin(TASK) .on(TASK_TEMPLATE.ID.eq(TASK.TASK_TEMPLATE_ID) .and(TASK.ENTITY_NAME.eq(entityName)) .and(TASK.ENTITY_ID.eq(entityId)) .and(TASK.DELETED.eq(Boolean.FALSE))) .where(TASK_TEMPLATE.TENANT.eq(TenantContext.getCurrentTenant())) .and(TASK_TEMPLATE.ID.in(rootTemplateIds)) .orderBy(TASK.ORDER.asc().nullsLast());
额外说明
如果某些场景下你必须把部分TASK条件留在WHERE里,那一定要加上OR TASK.TASK_TEMPLATE_ID IS NULL的判断,确保无关联的模板记录不会被过滤。不过这种写法不如把条件移到ON子句里直观,更推荐前者的做法哦。
内容的提问来源于stack exchange,提问作者user2323975
相关产品推荐
相关产品推荐

