Postgresql 将Postgres聚合函数转换为内联数组
有人问我如何在一行内的变量值列表上计算标准偏差。例如:Postgresql 将Postgres聚合函数转换为内联数组,postgresql,aggregate-functions,standard-deviation,Postgresql,Aggregate Functions,Standard Deviation,有人问我如何在一行内的变量值列表上计算标准偏差。例如: select name, x, y, z, stddev (x, y, z) from foo; 或 因此,本质上就像min=>least和max=>grest一样,我希望使用类似的方法将聚合stddev转换为普通函数 我已经能够创建一个自定义函数来计算基于标准公式的标准偏差,但是如果可能的话,我不得不选择使用内置函数。我试过这个: CREATE OR REPLACE FUNCTION std_deviation(variadic i
select
name, x, y, z, stddev (x, y, z)
from foo;
或
因此,本质上就像min=>least和max=>grest一样,我希望使用类似的方法将聚合stddev转换为普通函数
我已经能够创建一个自定义函数来计算基于标准公式的标准偏差,但是如果可能的话,我不得不选择使用内置函数。我试过这个:
CREATE OR REPLACE FUNCTION std_deviation(variadic inputs numeric[])
RETURNS numeric AS
$BODY$
DECLARE
result numeric;
BEGIN
select stddev (unnest (inputs))
into result;
return result;
end
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
它抱怨说:
ERROR: set-valued function called in context that cannot accept a set
这个错误消息上的流量并不短缺,但我不太明白如何将修复应用于我的简单函数
或者,从一开始就有更好的方法吗?在SELECT子句中设置返回函数SRF-例如unnest-是SQL标准的特定于PostgreSQL的扩展。通常不值得使用它,因为它不是它看起来的样子。此外,SRF不能在聚合函数中使用 在FROM子句中使用这些SRF函数,并在需要时使用子选择:
SELECT name, x, y, z, (SELECT stddev(v) FROM unnest(ARRAY[x, y, z]) v)
FROM foo
如果您真的想为此编写一个函数,请使用SQL语言,这一点更清楚&PostgreSQL可以优化它们的使用:
CREATE OR REPLACE FUNCTION std_deviation(variadic inputs numeric[])
RETURNS numeric AS
$BODY$
SELECT stddev(v) FROM unnest(inputs) v
$BODY$
LANGUAGE SQL IMMUTABLE;
SELECT子句中的Set返回函数SRF(例如unnest)是SQL标准的特定于PostgreSQL的扩展。通常不值得使用它,因为它不是它看起来的样子。此外,SRF不能在聚合函数中使用 在FROM子句中使用这些SRF函数,并在需要时使用子选择:
SELECT name, x, y, z, (SELECT stddev(v) FROM unnest(ARRAY[x, y, z]) v)
FROM foo
如果您真的想为此编写一个函数,请使用SQL语言,这一点更清楚&PostgreSQL可以优化它们的使用:
CREATE OR REPLACE FUNCTION std_deviation(variadic inputs numeric[])
RETURNS numeric AS
$BODY$
SELECT stddev(v) FROM unnest(inputs) v
$BODY$
LANGUAGE SQL IMMUTABLE;
这似乎奏效了
这似乎奏效了
事实证明pgnumerics已经有了一个功能
-- test=# select pgnumerics.stdev('{1345,1301,1368,1322,1310,1370,1318,1350,1303,1299}');
-- stdev
-- ------------------
-- 27.4639157198435
-- (1 row)
CREATE OR REPLACE FUNCTION pgnumerics.stdev (
X double precision []
) RETURNS double precision
AS $$
DECLARE
s double precision;
N integer;
i integer;
xx double precision;
sx double precision;
BEGIN
N := array_upper(X,1) - array_lower(X,1) + 1;
xx:= 0.0;
sx:= 0.0;
for i in 1..N loop
xx:= xx + X[i]*X[i];
sx:= sx + X[i];
end loop;
s := sqrt((N*xx - sx*sx) / (N*(N-1.0)));
return s;
END;
$$ LANGUAGE 'plpgsql';
事实证明pgnumerics已经有了一个功能
-- test=# select pgnumerics.stdev('{1345,1301,1368,1322,1310,1370,1318,1350,1303,1299}');
-- stdev
-- ------------------
-- 27.4639157198435
-- (1 row)
CREATE OR REPLACE FUNCTION pgnumerics.stdev (
X double precision []
) RETURNS double precision
AS $$
DECLARE
s double precision;
N integer;
i integer;
xx double precision;
sx double precision;
BEGIN
N := array_upper(X,1) - array_lower(X,1) + 1;
xx:= 0.0;
sx:= 0.0;
for i in 1..N loop
xx:= xx + X[i]*X[i];
sx:= sx + X[i];
end loop;
s := sqrt((N*xx - sx*sx) / (N*(N-1.0)));
return s;
END;
$$ LANGUAGE 'plpgsql';
哪一行生成错误消息?下面是一个创建错误的简化示例:选择min unnest array[1,2,3]。但是,我愿意使用任何方法来实现我的最终结果,即获取工作线的标准偏差,哪一行生成错误消息?下面是一个创建错误的简化示例:选择最小不测数组[1,2,3]。然而,我愿意接受任何能实现我最终结果的方法,即让标准偏差发挥作用