PostgreSQL - 计算百分比的函数

时间:2013-10-18 18:16:51

标签: postgresql aggregate-functions percentage

在postgresql中,如果我想要百分比,我只需写:

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并没有在函数内部总结。

有什么建议吗? 谢谢, 阿里。

2 个答案:

答案 0 :(得分:0)

要调试您的函数,请在文本文件中使用任意参数编写查询,然后使用psql运行它:

\i ./myfunc.sql

myfunc.sql的内容是:

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

这将允许您在将函数包装到函数中之前调试该函数。

当您完成并对一些样本的结果感到满意时,将其复制/粘贴到您的函数中,并将硬编码的测试值替换为适用的参数。

至于在有参数时优化它,我不知道在Postgres函数中运行解析分析的任何方法,但你可以得到一个计划 - 我最清楚 - 与函数将通过准备具有相同参数的语句来使用。所以你可以解释分析后者。


查看新的详细信息,请注意,如果您准备要在函数中运行的查询,则应始终获得1 - bar的零。

你在那里有一个错误,在某种意义上你需要保持状态从调用到下一个第一个返回预期结果。根据Per Pavel的建议,您实际上需要一个自定义聚合或自定义窗口函数。请参阅他在评论中建议的链接,以及:

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

答案 1 :(得分: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;