【问题标题】:jOOQ Dynamic WITH ClausejOOQ 动态 WITH 子句
【发布时间】:2020-10-05 04:27:03
【问题描述】:

我无法在 jOOQ 中找到有关如何动态构造 WITH 子句(即公用表表达式/CTE)的文档。我的用例是这样的:

  • 我需要嵌套动态创建的列,以便从这些动态创建的列中生成新数据
  • 例如,我正在创建一个新字段,它是完全外连接的非空结果。该字段仅在查询执行时可用,因此我需要将其存储在 WITH 子句中,以便在其他查询中引用它以进行额外计算。
  • 理想情况下,我可以动态请求 WITH 子句类型查询,并且可以通过将此连接的数据集放在其自己的 CTE 中以在下游引用中使用来解决这种依赖关系。

我正在尝试使用以下内容,但没有运气:

    SelectQuery<Record> query =
        getQuery(
            dslContext,
            selectFields,
            fromClause,
            groupFields,
            conditionClause,
            orderFields,
            query.getOffset(),
            query.getLimit());

    // WORKS JUST FINE
    Supplier<Stream<Map<String, Object>>> results = () ->
        query
            .fetchStream()
            .map(Record::intoMap);

    // make a nested query here. static for now.
    // DOES NOT WORK
    Supplier<Stream<Map<String, Object>>> resultsWith =
        () ->
            DSL.with("s1")
                .as(query) // Shouldn't I be able to reference a SelectQuery here?
                .select()
                .from(table(name("s1")))
                .fetchStream()
                .map(Record::intoMap);

query.toString() 看起来像这样:

select 
  table1.field1,
  coalesce( 
    table1.id, 
    table2.id) as table1.id_table2.id, 
  count(*) as table2.field1.count, 
  sum(table2.field2) as table2.field2.sum
  from table1.table1 as table1
  full outer join table2.table2 as table2
  on table1.id = table2.id
  where table1.field2 < 3000.0
  group by 
  table1.id_table2.id,
  table1.field1
  order by table1.field1 asc
  limit 100

我希望至少在其他下游查询中引用上面的coalesced 字段。理想情况下,在 jOOQ 中构造 WITH 子句时,我可以进行的动态引用的方式或数量完全不受限制。最后,我希望能够动态创建诸如此类的查询,这些查询也显示 CTE 引用 CTE:

-- WITH Clause usage is preferrable
with
  myFirstSelection as (
    select
      (id + 100) as newfield
    from table1.table1 n
  ),
  mySecondSelection as (
    select
      (newField + 200) as newerField
    from myFirstSelection
  )
select
* 
from mySecondSelection
;

-- Inline queries, while not ideal, would be permissible
select 
* 
from (
  select
  (newField + 200) as newerField
  from (
    select
      (id + 100) as newField
    from table1.table1 n
  ) as myFirstSelection
) as mySecondSelection
;

这可能吗?还是我仅限于静态表格和静态选择?


链接

堆栈溢出

jOOQ 网站

GitHub

jOOQ 谷歌组

【问题讨论】:

  • 为什么不起作用?
  • 我将创建一个新分支并尽快获取堆栈跟踪
  • @LukasEder 我重新排列了输入有效负载以创建我的查询。实际上,这个例子现在可以正常工作了。感谢您的审阅。不过,我有一个后续问题——文档中是否有一个示例用于使用循环来构建整个查询,cte-by-cte?如果您希望提出关于 S.O. 的新问题,请告诉我。
  • 很高兴它现在工作了。你查出来是什么原因了吗?回答您自己的问题可能会很有用,以防将来有人偶然发现这个问题......我很乐意在一个新问题中解释这个逐步创建的 CTE。

标签: java sql postgresql common-table-expression jooq


【解决方案1】:

这个问题原来是我的 JSON 有效负载中的一个属性中的 Jackson 反序列化问题,该属性变成了我的查询。当其中一个属性被转换为查询类的一部分时,我得到了NullPointerException。关于jOOQ,这个例子运行良好。另外,这是一个测试查询,它通过引用结果集中的相对位置来对第一个字段求​​和:

    /* Output looks like this : 
    +-----------------+
    |sum_of_everything|
    +-----------------+
    |              100|
    +-----------------+
     */

    Supplier<Stream<Map<String, Object>>> resultsWith =
        () ->
            dslContext
                .with("s1")
                .as(query)
                .select(sum(field("1", Integer.class)).as("sum_of_everything"))
                .from(table(name("s1")))
                .fetchStream()
                .map(Record::intoMap);

这个供应商可以在 RESTful 框架中作为响应返回,以将结果流式传输回请求者。

【讨论】:

    猜你喜欢
    • 2020-10-07
    • 2017-11-12
    • 1970-01-01
    • 2014-08-06
    • 2021-11-09
    • 2022-01-07
    • 1970-01-01
    • 2016-04-25
    • 2017-08-12
    相关资源
    最近更新 更多