0

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

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

4

2 回答 2

0

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

\i ./myfunc.sql

myfunc.sql 的内容是:

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

这将允许您在将函数包装到函数中之前对其进行调试。

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

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


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

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

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

于 2013-10-18T19:03:40.663 回答
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;
于 2013-10-21T16:20:12.443 回答