[英]How to use a SQL window function to calculate a percentage of an aggregate
我需要計算表格中各個維度的百分比。 我想通過使用窗口函數來計算分母來簡化事情,但是我遇到了一個問題,因為分子也必須是一個聚合體。
舉個簡單的例子,看下表:
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);
如果我只想計算 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
但是,我需要做的是計算 d1 中 d2 總和的總份額。 我正在尋找的輸出是這樣的:
"b";"x";1.00
"a";"x";0.25
"a";"y";0.75
所以我試試這個:
select d1, d2, sum(v)/sum(v) over (partition by d1)
from test
group by d1, d2;
但是,現在我收到一個錯誤:
ERROR: column "test.v" must appear in the GROUP BY clause or be used in an aggregate function
我假設這是因為它抱怨在分組子句中沒有考慮窗口函數,但是無論如何不能將窗口函數放在分組子句中。
這是使用 Greenplum 4.1,它是 Postgresql 8.4 的一個分支並共享相同的窗口函數。 請注意,Greenplum 不能進行相關子查詢。
我想你正在尋找這個:
SELECT d1, d2, sum(v)/sum(sum(v)) OVER (PARTITION BY d1) AS share
FROM test
GROUP BY d1, d2;
產生請求的結果。
在聚合函數之后應用窗口函數。 sum(sum(v)) OVER ...
的外部sum()
是一個窗口函數(附加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;
或(無 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;
或者@Mu 的變體。
旁白:Greenplum 在 4.2 版中引入了相關子查詢。 請參閱發行說明。
你需要用窗口函數來做這一切嗎? 聽起來您只需d1
和d2
對結果進行分組,然后將總和相加:
select d1, d2, sum(p)
from (
select d1, d2, v/sum(v) over (partition by d1) as p
from test
) as dt
group by d1, d2
這給了我這個:
d1 | d2 | sum
----+----+------------------------
a | x | 0.25000000000000000000
a | y | 0.75000000000000000000
b | x | 1.00000000000000000000
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.