我正在尝试使用task.task_Template_id.eq(task_template.id)的任务表上的内部联接来查询task_Template.id.in(1,4)的task_template表。因此,我想返回id为1或4的所有模板行,以及该模板的任务(如果存在)。
我的数据库中有两个模板,其中一个任务的task_template_id为1。
因此,我试图返回两个模板,其中一个任务为null,另一个任务为空。
但是我的查询似乎正在执行内部联接并且仅返回一个结果?
var query =
dsl.select(TASK_TEMPLATE.fields())
.select(TASK.fields())
.from(TASK_TEMPLATE)
.leftJoin(TASK)
.on(TASK_TEMPLATE.ID.eq(TASK.TASK_TEMPLATE_ID))
.where(TASK_TEMPLATE.TENANT.eq(TenantContext.getCurrentTenant()))
.and(TASK_TEMPLATE.ID.in(rootTemplateIds))
.and(TASK.ENTITY_NAME.eq(entityName))
.and(TASK.ENTITY_ID.eq(entityId))
.and(TASK.DELETED.eq(Boolean.FALSE))
.orderBy(TASK.ORDER.asc().nullsLast());
[当您离开联接时,您不能在TASK
表上写这样的谓词,否则,结果是您的左联接变成了内部联接。可以通过示例显示:
TASK_TEMPLATE
+----+--------+
| ID | TENANT |
+----+--------+
| 1 | A |
| 2 | B |
+----+--------+
任务
+----------------+-------------+
| TASK_TENANT_ID | ENTITY_NAME |
+----------------+-------------+
| 1 | X |
+----------------+-------------+
LEFT JOIN
之后的结果将是
+----+--------+----------------+-------------+
| ID | TENANT | TASK_TENANT_ID | ENTITY_NAME |
+----+--------+----------------+-------------+
| 1 | A | 1 | X |
| 2 | B | | |
+----+--------+----------------+-------------+
现在,如果要对ENTITY_NAME
(和其他字段)进行过滤(可能在NULL
之后是LEFT JOIN
,那么您将获得与首先将它们加入内部一样的效果)。您无法在LEFT JOIN
子句中过滤WHERE
-ed表中的列。
也许,您打算将其过滤在ON
子句中(作为LEFT JOIN
操作的一部分:]
var query =
dsl.select(TASK_TEMPLATE.fields())
.select(TASK.fields())
.from(TASK_TEMPLATE)
.leftJoin(TASK)
.on(TASK_TEMPLATE.ID.eq(TASK.TASK_TEMPLATE_ID))
// Move these here
.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))
// Remove them from here
// .and(TASK.ENTITY_NAME.eq(entityName))
// .and(TASK.ENTITY_ID.eq(entityId))
// .and(TASK.DELETED.eq(Boolean.FALSE))
.orderBy(TASK.ORDER.asc().nullsLast());
I've also discussed the difference between the ON
and WHERE
clauses in this blog post here。