【问题标题】:Joining a Table on VALUES() using JOOQ DSL API使用 JOOQ DSL API 在 VALUES() 上加入表
【发布时间】:2018-05-07 09:33:03
【问题描述】:

注意:

我有一个类似的问题,如何在中生成以下SQL JOOQ 但在过去的两天里,我完成了 99% 的工作,而这 给我带来了另一个问题 - 在这里被描述 - 作为我的 当前的解决方案没有回答我最初的问题,我删除了 另一个问题并创建了这个新问题 - 而不是替换 原始问题。

更新: 正如 Lukas Eder 指出的,将此问题更改为解决方案,生成的 SQL 是有效的。谢谢。

我有以下 SQL 查询 - 作为示例并将其转换为 JOOQ API 以为不同的表生成 SQL

SELECT c.*
FROM contacts c
   JOIN ( 
      VALUES
        (0, 13259), 
        (1, 12472),  
        (2, 12422)
  ) AS il(listindex, id) ON c.id = il.id
ORDER BY il.listindex;

我根据VALUES()JOINJOOQ手册创建了以下代码

注意:

这是一个独立的示例,它从字符串创建表、字段和名称。 这些代码实际上都没有在数据库中执行,它只是生成SQL

import static org.jooq.impl.DSL.row;
import static org.jooq.impl.DSL.values;
import static org.jooq.impl.DSL.table;
import static org.jooq.impl.DSL.field;
import static org.jooq.impl.DSL.name;

import org.jooq.DSLContext;
import org.jooq.Field;
import org.jooq.Name;
import org.jooq.Record;
import org.jooq.Row2;
import org.jooq.SQLDialect;
import org.jooq.SelectJoinStep;
import org.jooq.Table;
import org.jooq.impl.DSL;

public class StackoverflowJOOQQuestion {
    public static void main(String[] args) {
        DSLContext ctx = DSL.using(SQLDialect.H2);

        // create test data (as in the sql statement on top)
        Long[] lon = new Long[] { 13259l, 12472l, 12422l };
        Row2<Integer, Long>[] rows = new Row2[lon.length];

        for (int i = 0; i < rows.length; i++) {
            rows[i] = row(i, lon[i]);
        }

        // create Names, Fields and Tables
        // contacts table
        Name contactIdName = name("tContacts", "conIdContact");
        Field contactIdField = field(contactIdName, Long.class);
        Name contactNameName = name("tContacts", "conContactName");
        Field contactNameField = DSL.field(contactNameName, String.class);
        // values table
        Name nameTableValues = name("il");
        Table valuesTable = table(nameTableValues);
        Name nameTableValuesIndex = name("il", "listindex");
        Field valuesIndexField = field(nameTableValuesIndex, Integer.class);
        Name nameTableValuesId = name("il", "id");
        Field valuesIdField = field(nameTableValuesId, Long.class);

        // build the SQL query
        SelectJoinStep<Record> step = ctx.select(contactNameField).from("tContacts")
                .join(//
                        values(rows)//
                                // NOTE: also works with Strings, Names or Table and
                                // Fields as shown here
//                              .as("il", "listindex", "id")//
//                              .as(nameTableValues, nameTableValuesIndex, nameTableValuesId)//
                                .as(valuesTable, valuesIndexField, valuesIdField)//
                ).on(contactIdField.eq(valuesIdField));

        // print the query
        System.out.println(step.getSQL());
    }
}

但这会产生以下输出:

select "tContacts"."conContactName" from tContacts join (
    (select null "listindex", null "id" where 1 = 0) union all 
    (select * from (
            values (cast(? as int), cast(? as bigint))
                    , (cast(? as int), cast(? as bigint))
                    , (cast(? as int), cast(? as bigint))
            ) "il")
    ) "il" on "tContacts"."conIdContact" = "il"."id"

【问题讨论】:

  • 你为什么要删除另一个问题。您可以自行回答,这样当其他人遇到类似问题时,他们可以从您的经验中受益。感谢您的努力,两天为您,未来代码为 5 分钟。
  • 这个问题包含另一个问题,所以什么都没有丢失

标签: java sql jooq


【解决方案1】:

这不是错误,您生成的 SQL 也没有问题。您要加入的派生表确实具有所需的列名。观察:

(select null "listindex", null "id" where 1 = 0) union all ...

对于某些数据库,在使用派生列列表功能时会应用模拟。见:

直到最近,H2 数据库才增加了对派生列列表功能的支持,所以 jOOQ 生成的 SQL 可能已经过时了:

但出于向后兼容性的原因,已经转向新的语法是不明智的。

鉴于 H2 没有明确定义的主要版本控制方案,jOOQ 也不区分 H2 方言。

【讨论】:

  • 感谢您的回复,不知何故我忽略了选择null...union allpart。所以你说结果是正确的——这很好——会更新问题。
猜你喜欢
  • 1970-01-01
  • 2022-01-09
  • 2017-02-09
  • 2021-08-28
  • 2021-07-29
  • 2018-10-12
  • 2018-02-18
  • 2021-10-08
  • 2020-10-17
相关资源
最近更新 更多