如何在Jooq中查询元组上的非重复数组聚合?

How to query distinct array aggregate over tuple in Jooq?

提问人:Marius Schmidt 提问时间:11/11/2023 最后编辑:Marius Schmidt 更新时间:11/13/2023 访问量:27

问:

如何在JooQ中正确表达此SQL查询?我确实知道arrayAggDistinct()DSL方法,但是我无法表达行类型。

SELECT
    u.user_id,
    ARRAY_AGG(DISTINCT (g.group_id, g.group_name)) AS grouped_groups,
    ARRAY_AGG(DISTINCT (a.authority_id, a.authority)) AS grouped_authorities
FROM users u
         LEFT JOIN group_members gm ON u.user_id = gm.user_id
         LEFT JOIN groups g ON gm.group_id = g.group_id
         LEFT JOIN group_authorities ga ON g.group_id = ga.group_id
         LEFT JOIN authorities a ON ga.authority_id = a.authority_id
GROUP BY u.user_id;

编辑我发现,这创建了正确的查询

val groupRow: Row2<Long?, String?> = row(GROUPS.GROUP_ID, GROUPS.GROUP_NAME)
val groupsField: Field<Record2<Long?, String?>> = PostgresDSL.rowField(groupRow)
val authorityRow: Row2<Long?, String?> = row(AUTHORITIES.AUTHORITY_ID, AUTHORITIES.AUTHORITY)
val authoritiesField: Field<Record2<Long?, String?>> = PostgresDSL.rowField(authorityRow)
val jooqQuery = PostgresDSL.select(
    *USERS.fields(),
    arrayAggDistinct(groupsField).`as`("groups"),
    arrayAggDistinct(authoritiesField).`as`("authorities"),
).from(USERS)
    .leftJoin(GROUP_MEMBERS).on(USERS.USER_ID.eq(GROUP_MEMBERS.USER_ID))
    .leftJoin(GROUPS).on(GROUP_MEMBERS.GROUP_ID.eq(GROUPS.GROUP_ID))
    .leftJoin(GROUP_AUTHORITIES).on(GROUPS.GROUP_ID.eq(GROUP_AUTHORITIES.GROUP_ID))
    .leftJoin(AUTHORITIES).on(GROUP_AUTHORITIES.AUTHORITY_ID.eq(AUTHORITIES.AUTHORITY_ID))
.where(USERS.MAIL.eq(mail))
.groupBy(*USERS.fields())

但 rowField 方法被标记为已弃用,并且建议的 rowN 替代项不是在 arrayAggDistinct 中使用的正确类型。

sql postgresql jpa jooq

评论


答:

0赞 Lukas Eder 11/13/2023 #1

有许多问题要求在整个 API 中更普遍地接受扩展但不扩展的类型,例如:Row[N]SelectFieldField

  • #9123添加对 min(Row[N]) 和 max(Row[N]) 的支持
  • #10701添加对 ARRAY_AGG() 的支持
  • #11998查看 API 以更频繁地接受 SelectField 而不是 Field

jOOQ 没有广泛支持这些东西的主要原因是,很难向用户传达这些东西往往在 PostgreSQL 中起作用,但在其他任何地方都不起作用,因此,例如 Oracle、MySQL、SQL Server 用户会不断对 jOOQ API 看似承诺但没有兑现的问题感到失望。

在有办法彻底模拟这些东西之前,你必须使用(或你自己的纯SQL模板)来解决方法。PostgresDSL

评论

0赞 Marius Schmidt 11/23/2023
非常感谢您对产品:)的出色响应率