使用 Windows 功能分组 - Postgresql
Posted
技术标签:
【中文标题】使用 Windows 功能分组 - Postgresql【英文标题】:Group by with WIndows Function- Postgresql 【发布时间】:2021-12-23 12:09:20 【问题描述】:我知道,在这里使用 Group by 没有意义。但是我正在尝试一些东西并得到一个错误,说列成本应该在组中或在聚合函数中使用。我想了解内部发生了什么以及为什么逻辑不正确。假设我有一张桌子:
name | date | category | cost,
jill | 2019-04-01 | pen | 10 ,
jill | 2019-04-01 | pen | 40 ,
jill | 2019-04-01 | coat | 20 ,
Farida | 2019-03-01 | coat | 25,
Farida | 2019-03-02 | coat | 15
将代码编写为:
select
first_name, cast(o_date as date), sum(cost) over(partition by first_name) as tot
from tab1
group by
1,2;
根据查询,将执行第一个 group by,这将给出:
Jill | 2019-04-01
Farida | 2019-03-01
Farida | 2019-03-02
然后我们通过取成本列的总和来压缩行,但对于 first_name 的每个分区。
我期望输出为
Jill | 2019-04-1 | 50
Farida | 2019-03-01 | 60
Farida | 2019-03-02 |60
代码在没有 group by 子句的情况下工作正常(我已经知道该怎么做)。为什么我们不能在这里使用 group by?请问是什么原因导致代码不正确?
【问题讨论】:
报错信息很清楚,具体有什么不明白的地方?您不需要在这里对窗口求和,您需要每组的总和。 嗨,Stu,我想要每个分区(first_name)而不是组的总成本 在group by 1
之后定义一个窗口函数over(partition by first_name)
,例如按first_name 分组是没有用的。在窗口函数中按category
而不是first_name
分区会更有意义。
【参考方案1】:
sum()
后跟 OVER
子句不是聚合函数,尽管它与聚合函数同名。
因此,cost
在您的查询中既不是聚合函数的参数,也不是 GROUP BY
子句中的参数。
但您可以在聚合函数的结果上使用窗口(不是“窗口”)函数。
所以以下是允许的。 sum()
首先在cost
上用作聚合函数,然后然后在上面使用窗口函数sum()
。
SELECT first_name,
cast(o_date AS date),
sum(sum(cost)) OVER (PARTITION BY first_name) AS tot
FROM tab1
GROUP BY first_name,
cast(o_date AS date);
附带说明:我建议不要在GROUP BY
子句中使用列序号。这太容易搞砸了。更喜欢使用列表达式。
【讨论】:
非常感谢@sticky bit以上是关于使用 Windows 功能分组 - Postgresql的主要内容,如果未能解决你的问题,请参考以下文章
在windows上监视postgre 数据库 ,使用啥方式?