使用 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 数据库 ,使用啥方式?

使用 Windows 功能分组 - Postgresql

postgre与mysql区别

使用 postgre 数据库配置水晶报表 XI 的问题

在Windows 7的Emacs 24.3.1中,如何在dired中首先对目录进行分组?

postgre 批量删除表