PostgreSQL 是否自动检测 group by 子句中的唯一记录?

Does PostgreSQL automatically detect unique records in group by clause?

在 PostgreSQL 中不是必须将唯一列添加到 group by 子句中吗?

我通常使用 Microsoft SQL 服务器,我们必须在其中将所有需要的列添加到 group by 子句中。

PostgreSQL 查询:

DROP TABLE IF EXISTS temp_invoice_detail;
CREATE TEMP TABLE temp_invoice_detail(
    invoice_id integer,
    item_id integer,
    qty integer,
    warehouse_id integer    
);

ALTER TABLE temp_invoice_detail ADD CONSTRAINT temp_invoice_detail_result_pkey PRIMARY KEY (invoice_id, item_id);

insert into temp_invoice_detail (invoice_id, item_id, qty, warehouse_id) values (1, 1, 100, 1);
insert into temp_invoice_detail (invoice_id, item_id, qty, warehouse_id) values (1, 2, 200, 1);
insert into temp_invoice_detail (invoice_id, item_id, qty, warehouse_id) values (2, 1, 100, 1);

select invoice_id, item_id, sum(qty) as total_qty, warehouse_id
from temp_invoice_detail
group by invoice_id, item_id --should I add "warehouse_id" in group by clause?
order by invoice_id, item_id;

DROP TABLE IF EXISTS temp_invoice_detail;

我希望 PostgreSQL 显示错误消息:

column "temp_invoice_detail.warehouse_id" must appear in the GROUP BY clause or be used in an aggregate function

但查询运行s成功,returns3条记录(上面插入语句中的所有3条记录)。

invoice_id  item_id  total_qty  warehouse_id
1           1        100        1
1           2        200        1
2           1        100        1

在 MS-SQL 中,对于此查询可以 运行 没有错误,group by 子句必须是:

group by invoice_id, item_id, warehouse_id

这是因为您将 invoice_id, item_id 定义为 table 的主键,并且按唯一键分组就足够了,因为向组中添加更多列不会改变结果分组依据。

Quote from the manual

When GROUP BY is present, or any aggregate functions are present, it is not valid for the SELECT list expressions to refer to ungrouped columns except within aggregate functions or when the ungrouped column is functionally dependent on the grouped columns, since there would otherwise be more than one possible value to return for an ungrouped column. A functional dependency exists if the grouped columns (or a subset thereof) are the primary key of the table containing the ungrouped column

(强调我的)

这实际上是 SQL 标准允许的。 Postgres 甚至从分组依据中 删除 不需要的列(基于主键或唯一键的存在),因为这样可以提高性能。