在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并没有在函数内部总结。
有什么建议吗? 谢谢, 阿里。
答案 0 :(得分:0)
要调试您的函数,请在文本文件中使用任意参数编写查询,然后使用psql运行它:
\i ./myfunc.sql
myfunc.sql的内容是:
select x / sum(y) over (...) ...
这将允许您在将函数包装到函数中之前调试该函数。
当您完成并对一些样本的结果感到满意时,将其复制/粘贴到您的函数中,并将硬编码的测试值替换为适用的参数。
至于在有参数时优化它,我不知道在Postgres函数中运行解析分析的任何方法,但你可以得到一个计划 - 我最清楚 - 与函数将通过准备具有相同参数的语句来使用。所以你可以解释分析后者。
查看新的详细信息,请注意,如果您准备要在函数中运行的查询,则应始终获得1 - bar的零。
你在那里有一个错误,在某种意义上你需要保持状态从调用到下一个第一个返回预期结果。根据Per Pavel的建议,您实际上需要一个自定义聚合或自定义窗口函数。请参阅他在评论中建议的链接,以及:
答案 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;