【问题标题】:Jooq- Left inner joinJooq-左内连接
【发布时间】:2020-06-12 12:02:56
【问题描述】:

我正在尝试使用 task.task_Template_id.eq(task_template.id) 的任务表上的内部联接查询我的 task_template 表,其中 task_Template.id.in(1,4)。因此,我想返回 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());

【问题讨论】:

    标签: java mysql jooq


    【解决方案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 之后,那么您将获得相同的效果,就好像您首先将它们内联起来一样.您不能在 WHERE 子句中过滤来自 LEFT JOIN-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.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-30
      • 1970-01-01
      • 1970-01-01
      • 2017-06-29
      • 2010-09-16
      • 2017-08-15
      • 2010-10-06
      • 2015-03-04
      相关资源
      最近更新 更多