【问题标题】:Group by with WIndows Function- Postgresql使用 Windows 功能分组 - 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 分区会更有意义。

标签: sql postgresql group-by window-functions


【解决方案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
猜你喜欢
  • 2018-11-14
  • 1970-01-01
  • 2021-06-08
  • 2020-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-04
相关资源
最近更新 更多