简体   繁体   English

Jooq- 左内连接

[英]Jooq- Left inner join

I am trying to query my task_template table where the task_Template.id.in(1,4) with an inner join on the task table where task.task_Template_id.eq(task_template.id).我试图查询我的 task_template 表,其中 task_Template.id.in(1,4) 与任务表上的内部联接,其中 task.task_Template_id.eq(task_template.id)。 So I want to return all template rows where id is 1 or 4, and the task for that template if it exists.所以我想返回 id 为 1 或 4 的所有模板行,以及该模板的任务(如果存在)。

I have two templates in my DB, with one task with task_template_id of 1.我的数据库中有两个模板,其中一项任务的 task_template_id 为 1。

So I am trying to return two templates, where the task will be null in one and populated in the other.所以我试图返回两个模板,其中任务将在一个模板中为空,而在另一个模板中填充。

however my query seems to be doing an inner join and only returning one result?但是我的查询似乎正在执行内部连接并且只返回一个结果?

    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());

You cannot write predicates like that on the TASK table when you left join it, otherwise, the effect will be that your left join turns into an inner join.左连接时不能在TASK表上写这样的谓词,否则效果将是左连接变成内连接。 This can be shown by example:这可以通过示例显示:

TASK_TEMPLATE TASK_TEMPLATE

+----+--------+
| ID | TENANT |
+----+--------+
|  1 | A      |
|  2 | B      |
+----+--------+

TASK任务

+----------------+-------------+
| TASK_TENANT_ID | ENTITY_NAME |
+----------------+-------------+
|              1 | X           |
+----------------+-------------+

The result after a LEFT JOIN will be LEFT JOIN后的结果将是

+----+--------+----------------+-------------+
| ID | TENANT | TASK_TENANT_ID | ENTITY_NAME |
+----+--------+----------------+-------------+
|  1 | A      |              1 | X           |
|  2 | B      |                |             |
+----+--------+----------------+-------------+

Now, if you're filtering on ENTITY_NAME (and other fields), which may be NULL after your LEFT JOIN , then you will get the same effect as if you had inner joined them in the first place.现在,如果您对ENTITY_NAME (和其他字段)进行过滤,在您的LEFT JOIN之后它可能为NULL ,那么您将获得与首先将内部加入它们相同的效果。 You cannot filter columns from LEFT JOIN -ed tables in the WHERE clause.您不能从WHERE子句中的LEFT JOIN表中过滤列。

Maybe, you intended to filter them in your ON clause instead (as a part of your LEFT JOIN operation):也许,您打算在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 . 我还在这篇博文中讨论了ONWHERE子句之间的区别

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

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