Evi*_*ter 14 sql postgresql aggregate-functions window-functions greenplum
我需要计算表中各种尺寸的百分比.我想通过使用窗口函数来计算分母来简化事情,但是我遇到了问题,因为分子也必须是聚合.
举个简单的例子,请看下表:
create temp table test (d1 text, d2 text, v numeric);
insert into test values ('a','x',5), ('a','y',5), ('a','y',10), ('b','x',20);
Run Code Online (Sandbox Code Playgroud)
如果我只想计算d1中每一行的份额,那么窗口函数可以正常工作:
select d1, d2, v/sum(v) over (partition by d1)
from test;
"b";"x";1.00
"a";"x";0.25
"a";"y";0.25
"a";"y";0.50
Run Code Online (Sandbox Code Playgroud)
但是,我需要做的是计算d1中d2之和的总份额.我正在寻找的输出是这样的:
"b";"x";1.00
"a";"x";0.25
"a";"y";0.75
Run Code Online (Sandbox Code Playgroud)
所以我试试这个:
select d1, d2, sum(v)/sum(v) over (partition by d1)
from test
group by d1, d2;
Run Code Online (Sandbox Code Playgroud)
但是,现在我收到一个错误:
ERROR: column "test.v" must appear in the GROUP BY clause or be used in an aggregate function
Run Code Online (Sandbox Code Playgroud)
我假设这是因为它抱怨在分组子句中没有考虑窗口函数,但是无论如何窗口函数都不能放在分组子句中.
这是使用Greenplum 4.1,它是Postgresql 8.4的一个分支,并共享相同的窗口函数.请注意,Greenplum无法执行相关子查询.
Erw*_*ter 24
我认为你真正想要的是:
SELECT d1, d2, sum(v)/sum(sum(v)) OVER (PARTITION BY d1) AS share
FROM test
GROUP BY d1, d2;
Run Code Online (Sandbox Code Playgroud)
产生请求的结果.
窗口函数在聚合函数之后应用.在这个例子中,外部sum()in sum(sum(v))是一个窗口函数,它附加到OVER ...子句,而内部sum()是一个聚合.
实际上与:
WITH x AS (
SELECT d1, d2, sum(v) AS sv
FROM test
GROUP BY d1, d2
)
SELECT d1, d2, sv/sum(sv) OVER (PARTITION BY d1) AS share
FROM x;
Run Code Online (Sandbox Code Playgroud)
或者(没有CTE):
SELECT d1, d2, sv/sum(sv) OVER (PARTITION BY d1) AS share
FROM (
SELECT d1, d2, sum(v) AS sv
FROM test
GROUP BY d1, d2
) x;
Run Code Online (Sandbox Code Playgroud)
或@ Mu的变种.
旁白:Greenplum引入了4.2版的相关子查询.请参阅发行说明.
| 归档时间: |
|
| 查看次数: |
13458 次 |
| 最近记录: |