有人可以解释PostgreSQL如何决定哪些列需要在一个组或聚合函数中?

时间:2016-11-17 05:26:32

标签: postgresql

我已经在SO上找到了关于如何解决错误column "whatever" must appear in the GROUP BY clause or be used in an aggregate function的几个答案,但我还没有真正看到解释为什么以及选择了哪些列。

使用MySQL我可以在我的GROUP BY子句中添加一个列,它可以完美地运行。使用PostgreSQL,它基本上希望我将每列添加到组中(这不是我想要的)。这导致我在事后做分组,而且在大多数情况下,处理起来要慢得多。

我这里有2个表:membersreport_stats。第一个查询非常完美。

SELECT 
  members.id, members.name, members.username, members.email, members.site_id, members.created_at 
FROM members 
GROUP BY members.created_at, members.id 
ORDER BY members.created_at 
LIMIT 1000;

第二个查询不起作用。它希望我将approved列添加到组中。如果我这样做,那么它也需要view_stat_id

SELECT 
  report_stats.installation, report_stats.approved, report_stats.view_stat_id, report_stats.date 
FROM report_stats 
GROUP BY report_stats.date, report_stats.installation 
ORDER BY report_stats.date 
LIMIT 1000;

以下是这两个表格的结构:

Table "public.members"
     Column         |            Type             |           Modifiers           
------------------------+-----------------------------+-------------------------------
id                     | character varying(18)       | not null
site_id                | character varying           | 
email                  | character varying           | 
username               | character varying           | 
name                   | character varying           | 
created_at             | timestamp without time zone |
Indexes:
"members_pkey" PRIMARY KEY, btree (id)
"index_members_on_created_at" btree (created_at)
"index_members_on_email" btree (email)
"index_members_on_site_id" btree (site_id)


             View "public.report_stats"
  Column      |            Type             | Modifiers 
------------------+-----------------------------+-----------
view_stat_id     | character varying           |
installation     | smallint                    |
approved         | boolean                     |
date             | timestamp without time zone |

所以我的主要问题是,为什么第一个工作而不是第二个?是什么让我的成员表不同,我可以查询6列,只在GROUP BY中包含其中2列,但在第二列中,尝试查询4列,我需要GROUP BY中的所有4列? / p>

编辑:正在运行PostgreSQL 9.5.3 on x86_64-apple-darwin15.4.0, compiled by Apple LLVM version 7.3.0 (clang-703.0.31), 64-bit

1 个答案:

答案 0 :(得分:1)

一般情况下,Postgres会在您尝试选择单个值时抱怨,其中组中可能有许多值。示例#1有效,因为您按主键分组,这意味着其他值将是唯一的。 GROUP BY子句中的任何内容在每个组内部也是相同的,并且可以选择。

select的postgres手册说:

  

当存在GROUP BY或存在任何聚合函数时,它   对SELECT列表表达式无效以引用未分组   除聚合函数内或未分组列时的列   功能上依赖于分组列,因为它会   否则为一个未分组的人返回一个以上的可能值   柱。如果分组列(或a),则存在功能依赖性   其子集)是包含该表的表的主键   未分组的专栏。

https://www.postgresql.org/docs/9.5/static/sql-select.html#SQL-GROUPBY