JOOQ query to JOIN ON WITH clause

风流意气都作罢 提交于 2020-07-07 01:31:29

问题


How can I write a JOOQ query to join on a field from a "with" clause?

For example, I've tried:

create.with("a").as(select(
                           val(1).as("x"),
                           val("a").as("y")
                   ))
      .select()
      .from(tableByName("a")
      .join(ANOTHER_TABLE)
          .on(ANOTHER_TABLE.ID.eq(tableByName("a").field("x")))
      .fetch();

However, as the compiler doesn't know the type of tableByName("a").field("x") it cannot resolve which eq() method to use. Given that I know the type, is there a way I can provide it explicitly? Or is there another approach I should take to join on a field from a "with" clause?


回答1:


While I certainly agree with flutter's answer being a more desireable path to a solution here, I'll just quickly add a response that answers your specific compilation error question.

There are three things that are wrong with your current join predicate:

ANOTHER_TABLE.ID.eq(tableByName("a").field("x"))
  1. DSL.tableByName() is deprecated. It is generally recommended to use table(Name) instead.
  2. Such a dynamically constructed Table does not know of any of its field() references, thus table(name("a")).field("x") will return null
  3. The compilation error is due to your ID reference being of type Field<Integer> (probably), and thus the Field.eq() method expects a Field<Integer> argument as well. Without any knowledge about the type of your field "x", the jOOQ API / Java compiler infers Field<Object>, which is invalid.

So, the solution would be to write:

// field(Name, Class)
ANOTHER_TABLE.ID.eq(field(name("a", "x"), Integer.class))

// field(Name, DataType)
ANOTHER_TABLE.ID.eq(field(name("a", "x"), ANOTHER_TABLE.ID.getDataType()))

I.e. to use DSL.field(Name, Class<T>), or DSL.field(Name, DataType<T>) if you're using custom data type bindings / converters.




回答2:


What about declaring the CTE first? Explicit common table expressions

CommonTableExpression<Record2<Integer, String>> a =
  name("a").fields("x", "y").as(select(val(1), val("a")));

create.with(a)
      .select()
      .from(a)
      .join(ANOTHER_TABLE)
      .on(ANOTHER_TABLE.ID.eq(a.field("x")))
      .fetch();

If this does not work, you can always get the DataType<?> or the Class<?> via the Field, which you can get via the Table.



来源:https://stackoverflow.com/questions/44481307/jooq-query-to-join-on-with-clause

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!