且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

PostgreSQL-引用窗口函数中的另一个聚合列

更新时间:2023-11-20 14:50:16

认为您所追求的是一个窗口函数聚合函数,这是完全可能的,因为在聚合之后 后应用了窗口函数:

  SELECT名称
,group_name
,number1
,number2
,(number1 * number2)-SUM(number3)AS total_difference
,SUM((number1 * number2)-SUM( number3))OVER(按组名的分组)AS grand_total
FROM t
GROUP BY名,组名,编号1,编号2;

重复窗口函数中的聚合函数。另一种选择是子查询,例如 @张贴的戈登。但是请注意,他的帖子中的第一个查询当前与第二个查询不匹配。



相关答案有更多解释:




Here's the query:

SELECT name,
       group_name,
       number1, -- associated with either the name or the group_name
       number2,
       ...
       (number1 * number2) - SUM(number3) AS total_difference,
       SUM(total_difference) OVER (PARTITION BY group_name) AS grand_total
FROM t
GROUP BY name,
         group_name,
         number1,
         number2,
         ...;

A single group_name may have many associated names.

total_difference is generated for each name. My goal is for grand_total to be the sum of the total_difference for every name in group_name. total_difference is calculated for each name using number1 through numberx, some of which are related to the name and some of which are related to the group_name. Here's an example table (ignore the math, these numbers are clearly just made up):

name | group_name | number1 | number2 | number3 | total_difference | grand_total
-----+------------+---------+---------+---------+------------------+-------------
Fred | A          | 3       | 67      | 2       | 10               | 30
Amy  | A          | 5       | 25      | 45      | 20               | 30
Jim  | B          | 8       | 33      | 15      | 30               | 100
Tom  | B          | 2       | 6       | 35      | 45               | 100
Al   | B          | 6       | 89      | 4       | 25               | 100
...

The problem is that I clearly can't reference total_difference when I create grand_total, because it doesn't exist yet. I also can't just replicate the math:

SELECT ...
       SUM((number1 * number2) - SUM(number3)) OVER (PARTITION BY group_name) AS grand_total
...

because then I would have two difference aggregate functions with different group by arguments (I tried nesting window functions, but I knew that was a dumb idea even before I got the error message).

I recognize that I could just make the table and perform a join afterwards, and I have absolutely no problem with doing that. However, it bothers me that I can't see this... This is more a learning experience than anything.

How can I pull off what I'm going for. Do I even need a window function? Is this even possible?

This table is solely for presentation purposes, FYI. I'm using PostgreSQL 9.3.

I think what you are after is a window function over an aggregate function, which is totally possible since window functions are applied after the aggregation:

SELECT name
     , group_name
     , number1
     , number2
     , (number1 * number2) - SUM(number3) AS total_difference
     , SUM((number1 * number2) - SUM(number3)) OVER (PARTITION BY group_name) AS grand_total
FROM   t
GROUP  BY name, group_name, number1, number2;

Repeat the aggregate function inside the window function. The alternative is a subquery like @Gordon posted. Note, however, that the first query in his post does not currently match the second.

Related answer with more explanation: