JOOQ:从另一个表中选择按1列分组的列

时间:2018-02-12 19:01:04

标签: java postgresql spring-boot jooq

我不确定如何解释这个问题,但基本上我正在尝试做这样的事情:

private SelectHavingStep<Record> singleUserQuery(Collection<Condition> conditions) {
    return dsl.select(USER_T.fields())
              .select(DSL.arrayAggDistinct(PERMISSION_T.NAME).as("permissions"))
              .select(ROLE.NAME.as("role"))
              .select(ROLE.ROLE_TYPE.as("roleType"))
              .from(USER_T)
                .leftJoin(USER_ACCOUNT_PERMISSIONS)
                    .on(USER_ACCOUNT_PERMISSIONS.USER_ID.eq(USER_T.ID))
                .leftJoin(PERMISSION_T)
                    .on(PERMISSION_T.NAME.eq(USER_ACCOUNT_PERMISSIONS.PERMISSION))
                .leftJoin(ROLE)
                    .on(ROLE.ID.eq(USER_T.ROLE_ID))
              .where(conditions)
                .groupBy(USER_T.ID);
}

我有一个USER表,按照角色ID引用ROLE表,并希望我的用户结果始终包含ROLE表中的角色名称和类型。

这给了我以下错误PSQLException: ERROR: column "role.name" must appear in the GROUP BY clause or be used in an aggregate function。问题是我不确定如何解决这个问题,并希望听到任何建议。我非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

只需将ROLE.NAMEROLE.ROLE_TYPE添加到您的GROUP BY子句:

...
.groupBy(USER_T.ID, ROLE.NAME, ROLE.ROLE_TYPE)

或者,由于这是PostgreSQL(允许预测所有具有GROUP BY子句功能依赖性的列),添加ROLE.ID列可能就足够了:

...
.groupBy(USER_T.ID, ROLE.ID)

为什么会这样?

SQL初学者经常遇到的最大问题之一是不了解SQL子句中操作的逻辑顺序。在这种特殊情况下,了解GROUP BY条款&#34;发生&#34;是非常重要的。逻辑上在SELECT子句之前,意味着一旦按一组列分组,SELECT仍然可用的列集非常有限。作为一般经验法则,您只能选择:

  • GROUP BY子句
  • 中显示的列(或由列组成的表达式)
  • GROUP BY子句中出现的列上具有功能依赖性的列(或由列组成的表达式)。即如果按主键分组,则该表的所有其他列都是功能相关的,因此也可以选择它们。 (只有少数数据库实现此功能)
  • 在所有其他列上汇总函数

有关SQL操作顺序的更多信息,请访问:https://blog.jooq.org/2016/12/09/a-beginners-guide-to-the-true-order-of-sql-operations