Postgresql PortgreSQL-用于计算百分比的函数

Postgresql PortgreSQL-用于计算百分比的函数,postgresql,aggregate-functions,percentage,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); 如果我跑步

在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)
select rfreq(v1) from bruto;
 rfreq 
-------
     1
     1
     1
(3 rows)
现在,如果我想创建一个做同样事情的函数,我会写:

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

select v1/sum(v1) over() from ttt;
        ?column?        
------------------------
 0.11764705882352941176
 0.29411764705882352941
 0.58823529411764705882
(3 rows)
select rfreq(v1) from bruto;
 rfreq 
-------
     1
     1
     1
(3 rows)
Postgresql不是函数内部的求和

有什么建议吗? 非常感谢。
Ali。

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

\i ./myfunc.sql
myfunc.sql的内容将是:

select x / sum(y) over (...) ...
这将允许您在将函数包装到函数中之前调试该函数

当您完成并对一些示例的结果满意后,将其复制/粘贴到函数中,并在适用的情况下用参数替换硬编码的测试值

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


看到新的细节,请注意,如果您准备在函数中运行的查询,您应该始终得到1--bar和零

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


我在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;
创建或替换
功能相关频率(浮动8)
返回float8作为
$BODY$

不能将某些聚合函数或窗口函数的变量拆分为装箱sql函数。不支持。是的,我知道。但我觉得奇怪的是,没有(简单的)方法来构建计算百分比的函数。我相信很多人都会用它。它本身很有用,可以包含在更复杂的构造中。@user2895901-它可能很好,但这不是通常的用户请求。但这并非不可能——如果我理解的话,您可能需要创建一个自定义窗口函数。您可以用C编写自己的,也可以使用支持自定义窗口函数Ok的PL/v8语言。这听起来是个好办法。在提出这个问题之前,我将定制聚合作为一种可能的解决方案。丹尼斯在他的回答中提到了这一点,但我想我真正需要的是一个自定义窗口函数。谢谢,谢谢。我不知道这件事。