所以,我有五个表,我想在一个查询中取回它们。
parent_section(id, gate_id)
Assessment_Question(id,parent_section_id)
Assessment_question_multi_choice_option(id, question_id)
Assessment_answer_Group(id, entity_id)
Assessment_Answer(id,assessment_question_id, assessment_answer_Group_id)
我想列出所有的问题
错误是 Unknown column 'ideas_service.parent_section.id' in 'on clause'
以下是我的疑问
dsl.select()
.from(PARENT_SECTION,ASSESSMENT_ANSWER_GROUP)
.join(ASSESSMENT_QUESTION)
.on(PARENT_SECTION.ID.eq(ASSESSMENT_QUESTION.PARENT_SECTION_ID))
.leftJoin(ASSESSMENT_QUESTION_MULTI_CHOICE_OPTION)
.on(
ASSESSMENT_QUESTION_MULTI_CHOICE_OPTION.ASSESSMENT_QUESTION_ID.eq(
ASSESSMENT_QUESTION.ID))
.join(ASSESSMENT_ANSWER)
.on(ASSESSMENT_ANSWER_GROUP.ID.eq(ASSESSMENT_ANSWER.ASSESSMENT_ANSWER_GROUP_ID))
.where(PARENT_SECTION.GATE_ID.eq(gateId))
.fetch()
以前当我只想查询表的三个表,parent_Section_assessment_question和assessment_question_multi_choice的时候,我的查询是这样的,而且成功了。
var queryResult =
dsl.select()
.from(PARENT_SECTION)
.join(ASSESSMENT_QUESTION)
.on(PARENT_SECTION.ID.eq(ASSESSMENT_QUESTION.PARENT_SECTION_ID))
.leftJoin(ASSESSMENT_QUESTION_MULTI_CHOICE_OPTION)
.on(
ASSESSMENT_QUESTION_MULTI_CHOICE_OPTION.ASSESSMENT_QUESTION_ID.eq(
ASSESSMENT_QUESTION.ID))
.where(PARENT_SECTION.GATE_ID.eq(gateId))
.fetch()
我应该如何修改工作查询,使之也能列出一个联接问题上的assessment_Answer_Group( where assessment_answer_Group.entity_id = x) 之间的assessment_answer.answer_group_id。
澄清一下加盟结构
我在parent_section和assessment_Question之间做了一个内部连接,在assessment_question和assessment_multi_choice_option之间做了一个左连接。
answer_group和assessment_answer之间的连接是独立于这三个表的,应该是assessment_answer_group.entity_id = x,并且连接到assessment_Answer.answer_Group_id = assessment_answer_Grorup.id。
edit: 在akinas的评论之后,我的查询现在是这样的,它找到了assessment_answer_group,但是没有找到任何assessment_answers。
var queryResult =
dsl.select()
//below line is cross join with an always true join coniditon
.from(PARENT_SECTION.join(ASSESSMENT_ANSWER_GROUP).on(true))
.join(ASSESSMENT_QUESTION)
.on(PARENT_SECTION.ID.eq(ASSESSMENT_QUESTION.PARENT_SECTION_ID))
.leftJoin(ASSESSMENT_QUESTION_MULTI_CHOICE_OPTION)
.on(
ASSESSMENT_QUESTION_MULTI_CHOICE_OPTION.ASSESSMENT_QUESTION_ID.eq(
ASSESSMENT_QUESTION.ID))
.join(ASSESSMENT_ANSWER)
.on(ASSESSMENT_ANSWER_GROUP.ID.eq(ASSESSMENT_ANSWER.ASSESSMENT_ANSWER_GROUP_ID))
.where(PARENT_SECTION.GATE_ID.eq(gateId))
你得到这个错误的原因。
错误的原因是在 "on子句 "中,未知列 "its_service.parent_section.id"。
是因为你要加入 ASSESSMENT_QUESTION
到 ASSESSMENT_ANSWER_GROUP
,不要 PARENT_SECTION
在你的jOOQ查询中。
dsl.select()
.from(PARENT_SECTION,ASSESSMENT_ANSWER_GROUP)
.join(ASSESSMENT_QUESTION)
.on(PARENT_SECTION.ID.eq(ASSESSMENT_QUESTION.PARENT_SECTION_ID))
// ...
就像其他人在评论中指出的那样 你把逗号和列表分开的语法和ANSI JOIN语法混在一起了。无论是在 SQL 中,还是在 jOOQ 中,几乎都不推荐这样做。在jOOQ中,你上面的查询对应于这个SQL。
SELECT *
FROM PARENT_SECTION, (
ASSESSMENT_ANSWER_GROUP
JOIN ASSESSMENT_QUESTION
ON PARENT_SECTION.ID = ASSESSMENT_QUESTION.PARENT_ID
)
..
正如你所看到的,连接表达式没有任何意义 因为你在使用一个谓词连接两张表,而这个谓词引用了一张不在范围内的表。我最近写了一篇博客文章,通过添加这样的括号,可能有助于理解SQL JOIN语法。. 我认为括号在这里绝对有帮助。
这是我对正确连接的建议。
但是你还有一个问题。在SQL中,你不能轻易地将几个对多关系连接起来,否则你会得到卡托式产品。的意思。
PARENT_SECTION
可以有很多 ASSESSMENT_QUESTION
,它可以有许多 ASSESSMENT_QUESTION_MULTI_CHOICE_OPTION
. 这是2个层次的to-many关系,将重复的 PARENT_SECTION
每 ASSESSMENT_QUESTION
并再次 ASSESSMENT_QUESTION
每 ASSESSMENT_QUESTION_MULTI_CHOICE_OPTION
. 这种重复性的复制是可以的,因为你是在连接树的一个分支上进行的。ASSESSMENT_QUESTION
也有几个 ASSESSMENT_ANSWER
因为那是另一种对多关系。这就造成了问题。所以,你最终会得到一个cartesian product between ASSESSMENT_QUESTION_MULTI_CHOICE_OPTION
和 ASSESSMENT_ANSWER
因为你正在遍历连接树的两个独立的to-many分支,这绝对不是你想要的。
虽然你的5-join查询最终可能是正确的。句法上但还是会错 语义上!
你将不得不 使用XMLJSON(从jOOQ 3.14开始)或运行(至少)2个查询。
// Query 1 producing ASSESSMENT_QUESTION_MULTI_CHOICE_OPTION
dsl.select()
.from(PARENT_SECTION)
.join(ASSESSMENT_QUESTION)
.on(ASSESSMENT_QUESTION.PARENT_SECTION_ID.eq(PARENT_SECTION.ID))
.leftJoin(ASSESSMENT_QUESTION_MULTI_CHOICE_OPTION)
.on(ASSESSMENT_QUESTION_MULTI_CHOICE_OPTION.ASSESSMENT_QUESTION_ID
.eq(ASSESSMENT_QUESTION.ID))
.where(PARENT_SECTION.GATE_ID.eq(gateId))
.fetch();
// Query 2 producing ASSESSMENT_ANSWER and ASSESSMENT_ANSWER_GROUP
dsl.select()
.from(ASSESSMENT_ANSWER)
.join(ASSESSMENT_ANSWER_GROUP)
.on(ASSESSMENT_ANSWER_GROUP.ID.eq(ASSESSMENT_ANSWER.ASSESSMENT_ANSWER_GROUP_ID))
.where(ASSESSMENT_ANSWER.ASSESSMENT_QUESTION_ID.in(
select(ASSESSMENT_QUESTION.ID)
.from(ASSESSMENT_QUESTION)
.join(PARENT_SECTION)
.on(ASSESSMENT_QUESTION.PARENT_SECTION_ID.eq(PARENT_SECTION.ID))
.where(PARENT_SECTION.GATE_ID.eq(gateId))
))
.fetch();
然后你可以在你的客户端中把结果组合在一起。注意第二个查询不需要加入 PARENT_SECTION
和 ASSESSMENT_QUESTION
不再。A 半连接 (使用 IN
谓词)就可以了。
jOOQ支持一对一关系的隐式连接。. 上面的查询2也可以这样写,这可能更简单一些(尽管我建议你先研究一下 "真正的 "连接)。
dsl.select()
.from(ASSESSMENT_ANSWER)
.join(ASSESSMENT_ANSWER_GROUP)
.on(ASSESSMENT_ANSWER_GROUP.ID.eq(ASSESSMENT_ANSWER.ASSESSMENT_ANSWER_GROUP_ID))
.where(ASSESSMENT_ANSWER.assessmentQuestion().parentSection().GATE_ID.eq(gateId))
.fetch();