[英]jOOQ - join with nested subquery
Let's say I want to find out who wrote CLRS
in a book db (tables BOOK
, AUTHOR
with a junction table BOOK_AUTHOR
). 假设我想找出谁在书db中写了CLRS
(表BOOK
,具有连接表BOOK_AUTHOR
AUTHOR
)。
SelectConditionStep<Record1<String>> query = create
.select(AUTHOR.LASTNAME.as("AuthorName"))
.from(
(
BOOK.leftOuterJoin(BOOK_AUTHOR).on(BOOK.ID.eq(BOOK_AUTHOR.BOOKID))
).leftOuterJoin(AUTHOR).on(AUTHOR.ID.eq(BOOK_AUTHOR.AUTHORID))
)
.where(BOOK.TITLE.eq(CLRS_title))
;
A bit inefficient to match the entire table, just to select a single book. 匹配整个桌子效率低下,仅选择一本书。 I now want to select that book prior to the match. 我现在想在比赛之前选择那本书。
The jOOQ doc on this matter led me to believe that could look something like this: 关于此事的jOOQ文档使我相信它看起来可能像这样:
Table<Record1<Integer>> clrs = create
.select(BOOK.ID.as("bookID"))
.from(BOOK)
.where(BOOK.TITLE.eq(CLRS_title))
.asTable()
;
SelectJoinStep<Record1<String>> query = create
.select(AUTHOR.LASTNAME.as("AuthorName"))
.from(
(
clrs.leftOuterJoin(BOOK_AUTHOR).on(clrs.field("bookID").eq(BOOK_AUTHOR.BOOKID))
).leftOuterJoin(AUTHOR).on(AUTHOR.ID.eq(BOOK_AUTHOR.AUTHORID))
)
;
However, that fails to compile because 但是,由于无法编译,因此
Cannot resolve method 'eq(org.jooq.TableField<ch.cypherk.bookdb.public_.tables.records.BookAuthorRecord,java.lang.Integer>)'
in the join condition. 在加入条件下。
What's the correct way to write this join? 编写此联接的正确方法是什么?
You're dereferencing a column from your derived table using Table.field(String)
: 您正在使用Table.field(String)
从派生表中取消引用列:
clrs.field("bookID")
The type you're getting back is Field<?>
, with a wildcard. 您返回的类型是Field<?>
,带通配符。 Like with any generic type, once you have a wild card, a lot of operations (but not all) will no longer be possible on that type. 与任何通用类型一样,一旦有了通配符,该类型就将无法进行很多操作(但不是全部)。 Take List<?>
, for example. 以List<?>
为例。 You can still call List<?>.get()
to retrieve an Object
, but not List<?>.add(? element)
. 您仍然可以调用List<?>.get()
来检索Object
,但不能调用List<?>.add(? element)
。 In Field<?>
, you can no longer call eq()
, unless you cast the argument to a raw type. 在Field<?>
,您不能再调用eq()
,除非将参数强制转换为原始类型。
You can also coerce your field's <T>
type to the type you already know, eg by using Table.field(String, DataType<T>)
您也可以将字段的<T>
类型强制为已知的类型,例如,通过使用Table.field(String, DataType<T>)
clrs.field("bookID", BOOK.ID.getDataType())
Study your various options and you might discover the one(s) you might find most useful 研究您的各种选择,您可能会发现最有用的选择
You don't really need to 你真的不需要
Often with jOOQ, if you're having issues with derived tables as above, ask yourself is there really not an easier query I could write instead? 经常与jOOQ一起使用,如果您在使用上述派生表时遇到问题,请问自己是否真的没有一个我可以编写的更简单的查询?
What you really need here is a semi join . 您真正需要的是半连接 。 Write: 写:
// Assuming this static import
import static org.jooq.impl.DSL.*;
ctx.select(AUTHOR.LASTNAME)
.from(AUTHOR)
.where(AUTHOR.ID.in(
select(BOOK_AUTHOR.AUTHORID)
.from(BOOK_AUTHOR)
.join(BOOK).on(BOOK.ID.eq(BOOK_AUTHOR.BOOKID))
.where(BOOK.TITLE.eq(clrsTitle))
)
.fetch();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.