2013-10-18 54 views
0

在PostgreSQL,如果我想的百分比我只是寫:PortgreSQL - 函數來計算百分比

select x/sum(x) over() ... 

因爲裏面聚集函數不守規矩它不工作的功能。

我試圖找到一個解決方案,但沒有成功。 這是我真正需要的簡單版本,但我相信這個問題的解決方案肯定會指向正確的方向。


更多的細節......

如果我創建這個簡單的表:

create table ttt(v1 numeric, v2 numeric); 
insert into ttt values (2,1),(5,2),(10,4); 

如果我運行:

select v1/sum(v1) over() from ttt; --returns relative frequencies 

我得到:

select v1/sum(v1) over() from ttt; 
     ?column?   
------------------------ 
0.11764705882352941176 
0.29411764705882352941 
0.58823529411764705882 
(3 rows) 
現在

,如果我想創建一個函數,它做同樣的事情,我會寫:

create or replace function rfreq (double precision) 
returns double precision 
AS 
' 
select 
$1/sum($1) over() 
' 
LANGUAGE 'sql'; 

我得到:

select rfreq(v1) from bruto; 
rfreq 
------- 
    1 
    1 
    1 
(3 rows) 

PostgreSQL是不是一個函數內部總結。

有什麼建議嗎? 謝謝, 阿里。

+0

無法撕一些聚集函數或窗函數的給盒裝SQL函數。它不受支持。 –

+0

是的,我意識到這一點。但我覺得奇怪的是,沒有(簡單的)方法來構建函數來計算百分比。我很確定很多人會使用它。它本身很有用,並且包含在更復雜的結構中。 – Ali

+1

@ user2895901 - 它可能很好,但它不是通常的用戶請求。但這不是不可能的 - 如果我明白了,你會創建一個自定義窗口函數。你可以用C編寫自己的文件,或者你可以使用PL/v8語言,它支持自定義窗口函數http://pgxn.org/dist/plv8/1.3.0/doc/plv8.html –

回答

0

我發現通過PL/R郵件列表的解決方案瀏覽。

百分比(或相對頻率)可以用下面的代碼postgres的計算:

CREATE OR REPLACE 
FUNCTION rel_freq(float8) 
RETURNS float8 AS 
$BODY$ 
    var <- as.vector(farg1) 
    return((var/sum(var))[prownum] 
$BODY$ 
LANGUAGE plr WINDOW; 
0

要調試功能,寫在一個文本文件中的任意參數查詢,然後使用PSQL運行它myfunc.sql的

\i ./myfunc.sql 

內容是:

select x/sum(y) over (...) ... 

這將允許您在將函數包裝到函數中之前對其進行調試。

當您完成並且對少數樣本的結果滿意時,將其複製/粘貼到您的函數中,並在適用的情況下將硬編碼測試值替換爲參數。

至於優化它有參數時,我不知道有任何方法可以在Postgres函數中運行解釋分析,但是您可以得到一個計劃 - 我最清楚 - 與該函數將通過準備具有相同參數的語句來使用。所以你可以解釋一下分析後者。


看到新的細節,注意,如果你準備,你在函數運行查詢,你應該總是讓1 - 零吧。

你在那裏有一個錯誤,在某種意義上你需要保持狀態從一個調用到下一個返回預期的結果。根據Pavel的建議,您實際上需要一個自定義聚合或自定義窗口功能。查看評論他建議的鏈接,以及:

http://www.postgresql.org/docs/current/static/xaggr.html

+0

謝謝。我不知道這個。 – Ali