所以,我从这里学习windows函数,https://www.postgresqltutorial.com/postgresql-window-function/
在开始窗口函数部分之前,先简要介绍一下聚合函数和group by子句。
这些是我根据教程使用的参考表:
据我了解,应该在 SELECT 和 GROUP BY 子句中使用相同的字段。例如
SELECT p.group_id, avg(p.price) from PRODUCTS p GROUP BY p.group_id;
否则 PostgreSQL 会报错:
column "" must appear in the GROUP BY clause or be used in an aggregate function.
但是,我对以下查询的结果有点困惑:
select group_name,avg(price) from product_groups inner join products p using (group_id) group by group_id;
首先,我在 select 和 group by 中使用不同的列,分别是
group_name
和 group_id
。但是,它不会抛出类似于上面的错误!
并且,它给出了以下结果。看起来
group_name
和 group_id
在这里可以互换使用。任何人都可以解释一下这是怎么回事吗?
您对
GROUP BY
规则的理解已经几乎完整了。一般来说,无论出现在 SELECT
子句中的列也必须出现在 GROUP BY
中。然而,ANSI 标准中有一个例外,它规定如果 GROUP BY
中的一列 uniquely 确定了其他列的值,那么其他列也可以出现在 SELECT
子句中。
仔细看看你的第二个查询:
SELECT group_name, AVG(price) -- valid, because if we know
FROM product_groups -- group_id then we also know
INNER JOIN products p USING (group_id) -- group_name
GROUP BY group_id;
在
products
表中,如果 group_id
是主键或唯一键,那么如果我们为 group_id
选择某个值,我们也唯一知道 group_name
是什么。如果是这样,那么从技术上讲,您的第二个查询是符合 ANSI 的。 Postgres 比大多数其他数据库更倾向于严格遵循 ANSI 标准,因此它接受您的查询作为有效的查询。