【问题标题】:How to re-use one CTE in another CTE in jOOQ如何在 jOOQ 的另一个 CTE 中重用一个 CTE
【发布时间】:2020-04-01 13:40:29
【问题描述】:

在 jOOQ 中,我在以后的 CTE 中重新使用了 CTE。我正在尝试按年份和学校汇总学生完成记录。我正在使用 jOOQ 3.11.2 和 postgres 9.4。

我有工作的 SQL 代码。但是在 jOOQ 中,我返回了 null 值。

这似乎是我如何在以后的 CTE 中重复使用一个 CTE 的问题。

一开始我以为是count()的使用有问题。从手册来看,count() 的使用似乎是正确的。作为测试,我删除了查询中对 count() 的所有引用,但仍然得到相同的错误。

我找不到在 jOOQ 中重用或链接 CTE 的示例。在 SQL 中很简单,如下所示:SQL - Use a reference of a CTE to another CTE 但我在 jOOQ 中没有掌握它的窍门。

在 Intellij 上以调试模式运行时,我看到一个错误,即无法在第二个 CTE 中评估 select() 语句。

Cannot evaluate org.jooq.impl.SelectImpl.toString()

这是一个显示我在做什么的最小示例。

 CommonTableExpression<Record4<String, String, String, Year>> cteOne = name("CteOne")
    .fields("SCHOOL","STUDENT_NAME", "COURSE_COMPLETED", "YEAR_COMPLETED")
    .as(
            select( a.NAME.as("SCHOOL")
                    , a.STUDENT_NAME
                    , a.COURSE_DESCRIPTION.as("courseCompleted"),
                    , a.YEAR_COMPLETED 
                    )
                    .from(a)
                    .orderBy(a.YEAR_COMPLETED)
    );

CommonTableExpression<Record3<String, Year, Integer >> cteCounts = name("cteCounts")

    .fields("SCHOOL", "YEAR_COMPLETED", "NUM_COMPLETED" )

    .as( with(cteOne)
                    .select(
                            , field(name("cteOne","SCHOOL"), String.class)
                            , field(name("cteOne","YEAR_COMPLETED"), Year.class)
                            , count().as("NUM_COMPS_LOGGED")
                    )
                    .from(cteOne)
                    .groupBy(
                            field(name("cteCompsList","YEAR_COMPLETED"), Year.class)
                          , field(name("cteOne","SCHOOL"), String.class)
                    )
                    .orderBy(
                            field(name("cteCompsList","YEAR_COMPLETED"), Year.class)
                          , field(name("cteOne","SCHOOL"), String.class)
                    )
    );

有人可以指出我正确的方向吗?

【问题讨论】:

    标签: java sql common-table-expression jooq


    【解决方案1】:

    就像在查询的普通 SQL 版本中一样,cteCounts 不应该有 with(cteOne) 子句:

    WITH 
      cteOne (columns...) AS (select...),
      cteCounts (columns...) AS (select referencing cteOne, no "with cteOne" here...)
    SELECT ...
    FROM ...
    

    删除它,您的查询应该没问题

    【讨论】:

    • 谢谢。我删除了 with(cteOne) 子句并得到一个错误,即 jooq 生成的 SQL 没有对 cteOne 的引用。我尝试了 cteOne 中的其他地方,例如:with(cteOne).name(...) 然后name(...).with(cteOne).fields(...) 然后name(...).fields(...).with(cteOne).as(...)。 Intellij 说没有一个是正确的。做类似的事情:Result&lt;?&gt; result2 = create().with(t1) .with(t2) .select( ...).from(t1, t2).fetch();工作正常,但 cteCounts 在 CTE 的定义中是否也需要 with()
    • @peterJ:非常感谢您的评论。你介意问一个新问题吗? Stack Overflow 的评论格式让你很难理解我回答后你可能一直在做的事情。
    • 是的,评论格式让人难以理解。我在这里发布了一个新问题:stackoverflow.com/questions/59271846/…
    • @peterJ:谢谢。稍后会研究它
    • @LukasEder 是不是有些方言支持nested cte?您能否发布“普通”SQL 版本的“非工作”查询是什么样的?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-09
    • 1970-01-01
    • 1970-01-01
    • 2022-01-07
    • 1970-01-01
    • 2015-11-16
    • 1970-01-01
    相关资源
    最近更新 更多