【问题标题】:Postgres SQL: column must appear in the GROUP BY clause or be used in an aggregate functionPostgresql:列必须出现在 GROUP BY 子句中或在聚合函数中使用
【发布时间】:2021-02-06 00:09:22
【问题描述】:

(Postgres)

我不清楚以下几点:我正在从 STUDY_T 中选择各种字段,这些字段可能是带有聚合函数的子选择。我正在检索的一个独立字段是一个 LOOKUP_T 连接 lookupStudyType.description,它与任何聚合函数都不相关。但我得到了错误

ERROR:  column "lookupstudytype.description" must appear in the GROUP BY clause or be used in an aggregate function
LINE 3:     lookupStudyType.description     AS studyTypeDescription,...

为什么我不仅需要按s.id 分组,还需要按lookupStudyType.description 分组(而其他s. 分组不是必需的)?

        SELECT 
            s.id                                        AS id, 
            lookupStudyType.description                 AS studyTypeDescription, 
            s.name                                      AS name, 
            s.abbreviation                              AS abbreviation, 
            s.start_date                                AS startDate, 
            s.end_date                                  AS endDate, 
            (SELECT COUNT(r.id)   
                FILTER 
                (WHERE r.status_id IN (76, 77) ))       AS  recallCount, 
            (SELECT COUNT(DISTINCT sp.id))              AS  participantCount, 
            (SELECT MAX(r.created_date) 
                FILTER 
                (WHERE r.status_id IN (76,77) ))        AS lastRecall,
            s.login_access_required                     AS loginAccessRequired, 
            s.description                               AS description, 
            s.custom_participant_exit_message           AS customParticipantExitMessage 
        FROM study_t s 
        INNER JOIN lookup_t lookupStudyType 
           ON s.study_type_id = lookupStudyType.id 
        INNER JOIN study_staff_t ss 
            ON s.id = ss.study_id 
        INNER JOIN users_t u 
            ON ss.researcher_id = u.id 
        LEFT JOIN study_participants_t sp 
            ON s.id = sp.study_id 
        LEFT JOIN recalls_t r 
            ON r.user_id = sp.user_id 
        WHERE  u.user_name = 'test@test.com'
        GROUP BY 
            s.id
        ORDER  BY s.abbreviation ASC

【问题讨论】:

  • 错误似乎很明显。在group by 中包含该列。
  • 问题是 为什么 。这是一个独立的列,与任何 STUDY_T 字段无关。
  • PostgreSQL 不知道列的独立性。作为 SQL 的一般规则,所有列必须在聚合查询中进行分组或聚合。然而,一些 DBMS 的工作方式有所不同。
  • 那么为什么不需要对其他STUDY_T 列进行分组呢?其他 s. 字段都不是必需的。
  • 这是因为 id 是您的主键:如果分组列(或其子集)是包含未分组列的表的主键,则存在功能依赖关系。 postgresql.org/docs/current/sql-select.html

标签: sql postgresql


【解决方案1】:

作为一般规则,GROUP BY 子句中未列出的任何列都应聚合显示在SELECT 列表中。

例如s.name 应该显示为max(s.name)min(s.name),因为它不在GROUP BY 列表中。但是,PostgreSQL 为GROUP BY 子句实现了功能依赖(SQL 标准特性),并检测到s.name 依赖于s.id 列(这可能是一个PK);简而言之,每个s.id 都有一个可能的值s.name。因此,在 PostgreSQL 中不需要聚合该列(可以,但不是必需的)。

另一方面,对于lookupStudyType.description,PostgreSQL 无法确定它是否在功能上依赖于s.id。您需要将其聚合为 max(lookupStudyType.description)min(lookupStudyType.description),或任何其他聚合表达式。

附带说明,我很少看到在其他数据库中实现功能依赖。 PostgreSQL 不是很棒吗? (我与 PostgreSQL 没有任何关系)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-06
    • 2020-11-04
    • 1970-01-01
    • 2018-05-16
    • 1970-01-01
    • 2013-11-05
    相关资源
    最近更新 更多