Jooq-左内连接

问题描述 投票:1回答:1

我正在尝试使用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());
java mysql jooq
1个回答
1
投票

[当您离开联接时,您不能在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

© www.soinside.com 2019 - 2024. All rights reserved.