簡體   English   中英

如何使用 SQL 窗口函數計算聚合的百分比

[英]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 版中引入了相關子查詢。 請參閱發行說明。

你需要用窗口函數來做這一切嗎? 聽起來您只需d1d2對結果進行分組,然后將總和相加:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM