繁体   English   中英

Jooq- 左内连接

[英]Jooq- Left inner join

我试图查询我的 task_template 表,其中 task_Template.id.in(1,4) 与任务表上的内部联接,其中 task.task_Template_id.eq(task_template.id)。 所以我想返回 id 为 1 或 4 的所有模板行,以及该模板的任务(如果存在)。

我的数据库中有两个模板,其中一项任务的 task_template_id 为 1。

所以我试图返回两个模板,其中任务将在一个模板中为空,而在另一个模板中填充。

但是我的查询似乎正在执行内部连接并且只返回一个结果?

    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 (和其他字段)进行过滤,在您的LEFT JOIN之后它可能为NULL ,那么您将获得与首先将内部加入它们相同的效果。 您不能从WHERE子句中的LEFT JOIN表中过滤列。

也许,您打算在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());

我还在这篇博文中讨论了ONWHERE子句之间的区别

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM