11

テーブルのさまざまな次元のパーセンテージを計算する必要があります。私は分母を計算するためにウィンドウ関数を使用して事を簡素化したいと思いますが、分子は集合体でなければならないので問題があります。簡単な例としてSQLウィンドウ関数を使用して集計の割合を計算する方法

、次の表を取る:

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の合計の全体的なシェアを計算することです。今、私はエラーを取得し、しかし

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 

私はこれがあるためであると仮定していますので、私はこれを試してみてください

"b";"x";1.00 
"a";"x";0.25 
"a";"y";0.75 

:私は探しています出力はこれですウィンドウ関数がグループ化節で考慮されていないと不平を言っていますが、ウィンドウ化関数をグループ化節に入れることはできません。

これは、PostgreSQL 8.4のフォークで、同じウィンドウ機能を共有するGreenplum 4.1を使用しています。 Greenplumは相関サブクエリを実行できないことに注意してください。

答えて

16

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 

私にこれを与える:あなただけのグループにあなたがd1d2であり、その後、合計を合計結果を必要とするような音:

SELECT d1, d2, sum(v)/sum(sum(v)) OVER (PARTITION BY d1) AS share 
FROM test 
GROUP BY d1, d2; 

要求された結果を生成します。

集合関数の後にウィンドウ関数が適用されます。 sum(sum(v))の外側の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; 

またはμの変種@。

脇に:Greenplumはバージョン4.2で相関サブクエリを導入しました。 See release notes.

+0

素晴らしいよ!それは私が後にしたものです。意味をなさないドキュメントは、このようなことについてはっきりしているわけではありません。 – EvilPuppetMaster

+0

@erwinBrandsletter私の人生を保存しました!ありがとう – isJustMe

1

窓関数を使用してすべて行う必要がありますか?私はあなたが実際に探していることはこれだと思います

d1 | d2 |   sum   
----+----+------------------------ 
a | x | 0.25000000000000000000 
a | y | 0.75000000000000000000 
b | x | 1.00000000000000000000 
+1

本当に、実際にはうまくいきます。しかし、サブクエリを使わないでこれをやりたいのは、実際にはBIツール(Tableau)に入る必要があり、サブクエリが問題を引き起こすからです。 – EvilPuppetMaster

関連する問題