【问题标题】:Using PosgreSQL array_agg with join alias in JOOQ DSL在 JOOQ DSL 中使用带有连接别名的 PosgreSQL array_agg
【发布时间】:2019-01-16 03:24:59
【问题描述】:

我想将此 SQL 查询转换为 JOOQ DSL。

select "p".*, array_agg("pmu") as projectmemberusers
from "Projects" as "p"
join "ProjectMemberUsers" as "pmu" on "pmu"."projectId" = "p"."id"
group by "p"."id";

目前我已经尝试使用 JOOQ 做这样的事情:

val p = PROJECTS.`as`("p")
val pmu = PROJECTMEMBERUSERS.`as`("pmu")
val query = db.select(p.asterisk(), DSL.arrayAgg(pmu))
        .from(p.join(pmu).on(p.ID.eq(pmu.PROJECTID)))
        .groupBy(p.ID)

这不起作用,因为 DSL.arrayAgg 需要 Field<T> 类型的东西作为输入。

我是 JOOQ 的新手,不是 SQL 专业人士。非常感谢详细的解释和改进建议。

【问题讨论】:

  • 坦率地说,我不明白原始查询是如何工作的。 array_agg() 应该收到一个列,并且您正在向它传递一个表别名。我错过了什么?
  • 嗯,这个查询实际上对我有用。也许看看这个blog.jooq.org/2017/01/12/…(页面底部“替代语法:PostgreSQL”)
  • @AlexeySoshin:您在投影中引用了一个表以在 PostgreSQL 中创建嵌套记录。
  • @LukasEder,是的,已经证实了这一点,尽管它在 PostgreSQL 中没有很好地记录。不过,我的假设是否正确,即 jOOQ 仍然不支持它?
  • @AlexeySoshin:没错,目前不支持。可以比较两个表t1 = t2,但还不能投影它们。嵌套记录在 jOOQ 中仍处于试验阶段。

标签: sql postgresql kotlin jooq


【解决方案1】:

首先,语法确实有效,在 SQL Fiddle 中检查了这一点:http://sqlfiddle.com/#!17/e45b7/3

但没有详细记录:https://www.postgresql.org/docs/9.5/static/functions-aggregate.html https://www.postgresql.org/docs/current/static/rowtypes.html#ROWTYPES-USAGE

这可能是 jOOQ 目前不支持此功能的原因:https://github.com/jOOQ/jOOQ/blob/master/jOOQ/src/main/java/org/jooq/impl/DSL.java#L16856

目前唯一可以使用的语法是单个字段:DSL.arrayAgg(pmu.field(1))

【讨论】:

    【解决方案2】:

    您正在寻找的是一种通过 jOOQ API 表达 PostgreSQL 的“匿名”嵌套记录的方法,类似于此功能请求中的请求:https://github.com/jOOQ/jOOQ/issues/2360

    这目前在 jOOQ API 3.11 版本中是不可能的,但肯定会在未来。

    解决方法 1

    您可以尝试在表类型的 Row[N]<...> 表示上使用实验性的 DSL.rowField() 方法。这可能会也可能不会起作用,因为目前不支持该功能。

    解决方法 2

    一种解决方法是创建一个类型:

    create type my_type as (...) -- Same row type as your table
    

    还有一个观点:

    create view x as
    select "p".*, array_agg("pmu"::my_type) as projectmemberusers
    from "Projects" as "p"
    join "ProjectMemberUsers" as "pmu" on "pmu"."projectId" = "p"."id"
    group by "p"."id";
    

    然后使用代码生成器获取生成的类型。

    【讨论】:

    • 我怎样才能得到一个表类型的Row[N]<...> 表示?我试着做DSL.arrayAgg(DSL.rowField(pmu.fieldsRow()))。但是rowField(..) 不能用那个参数调用。
    • @TobiasMarschall:生成的表已经生成了row() 方法。这有帮助吗?如果没有,请随时提出新问题
    • 我创建了一个后续问题。 stackoverflow.com/questions/52003995/…
    猜你喜欢
    • 2021-04-03
    • 2022-01-07
    • 2012-08-05
    • 2017-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-25
    • 2021-08-03
    相关资源
    最近更新 更多