在JOOQ DSL中将PosgreSQL array_agg与连接别名一起使用

时间:2018-08-08 18:56:57

标签: sql postgresql kotlin jooq

我想将此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专业人员。高度赞赏详细的解释和改进建议。

2 个答案:

答案 0 :(得分:3)

首先,语法确实有效,请在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))

答案 1 :(得分:2)

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

从3.11版开始,当前无法在jOOQ API中实现,但肯定会在将来。

解决方法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";

然后使用代码生成器选择结果类型。