PostgreSQL 要求 GROUP BY,虽然我似乎不需要它

PostgreSQL asking for a GROUP BY although it seems I don't need it

我查看了文档,但我不明白为什么要我 GROUP BY。 这是我的要求:

SELECT n.title, n.date,
jsonb_agg(
  jsonb_build_object('type', fb.type, 'name', fb.name, 'id', fb.id)
) as illus
FROM news n
LEFT JOIN files fb
  ON fb.id = (n.illustration ->> 'val')::integer
where n.id = '38'

PostgreSQL 要求我将 n.titlen.date 放在 GROUP BY 子句中,但我不明白:我只有一个结果,因为我有 WHERE 子句. 当我添加 GROUP BY n.title, n.date 时,我得到了我的结果,但我应该没有这条线,不是吗? 如果我阅读了文档(以及关于 Whosebug 的其他类似问题),GROUP BY 就是当你有几个可能的结果并且你想...将它们分组时:)

您的 SELECT 子句。

对于聚合函数,PostgreSQL 获取一组中的所有行,将它们放入此函数中,并只返回一个结果,即函数的输出。 PostgreSQL 会将您的结果视为一个大组,如果您不告诉它应该做什么 GROUP BY 来制作(可能)更多因此更小的组。

对于结果集中的所有其他非聚合列,PostgreSQL 现在也只需要为每组提供一个结果,因为您的查询结果每组只有一行(因为这是聚合函数有效)。 PostgreSQL 不会随机选择组中出现的值之一,这将是不一致的并且没有任何意义。
相反,它确保它可以选择的所有值都完全相同,这意味着一个输出列的所有值在一组内都是相同的。因此这个值对这个组有一些意义,并用在结果中。

你想在这里争论的是,你的查询 returns 只有 news 的一行(可能多次),因此“总计”组(由所有返回的行组成没有分组的查询)只有一个不同的 news 行,因此所有请求的值每组都是常量。
只是说:这个说法确实是真的。
但是:DBMS 只是不检查这个。我认为这是因为它不期望查询的列是常量(如果它不是明显的常量,例如文字)。

这意味着,不检查 WHERE 子句以强制每组查询列的唯一性。因此 PostgreSQL 抱怨你的查询。

那么在这种情况下您可以做什么:只是 GROUP BY n.idGROUP BY n.title, n.date。我希望很清楚,为什么第二个有效。第一种方法有效,因为 PostgreSQL 看到您正在按 nPRIMARY KEY(或更一般的:UNIQUE 约束)进行分组,因此识别出 n 的所有列因为该组中的所有行都只有一个值。
这意味着您期望在 WHERE 子句中检查的内容仅在 GROUP BY 子句中检查:功能依赖性。