我被问到如何对一行中的变量值列表进行标准偏差。例如:
nodejs
或
select
name, x, y, z, stddev (x, y, z)
from foo;
所以基本上就像select
order_no, a, b, c, d, e, f, stddev (a, b, c, d, e, f)
from foo;
=> min
和least
=> max
,我想以类似的方式将聚合的stddev变成" normal"功能
我已经能够创建一个自定义函数来根据标准公式计算标准差,但是如果可能的话,我不能帮助但更喜欢使用内置函数。我试过这个:
greatest
它抱怨道:
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;
此错误消息上没有流量不足,但我无法弄清楚如何将修复应用于我的简单功能。
或者,从一开始就有更好的方法吗?
答案 0 :(得分:2)
f :: (Int -> Bool) -> [Int] -> [Bool]
f = map
g :: Int -> Bool -> [Int] -> [Bool]
g n b = map (\n' -> (n' == n) == b)
λ> let ns = [42, 13, 42, 17]
λ> f (== 42) ns
[True,False,True,False]
λ> g 42 True ns
[True,False,True,False]
λ> g 42 False ns
[False,True,False,True]
子句中的设置返回函数(SRF) - 例如unnest
- 是SQL标准的PostgreSQL特定扩展。并且通常不值得使用它(因为它不是它的样子)。此外, SRF不能在聚合函数中使用。
使用SELECT
子句中的这些SRF函数(并在需要时使用子选项):
FROM
如果你真的想为此编写一个函数,请使用SELECT name, x, y, z, (SELECT stddev(v) FROM unnest(ARRAY[x, y, z]) v)
FROM foo
语言(它更清晰,PostgreSQL可以优化它们的使用):
SQL
答案 1 :(得分:1)
这似乎可以解决问题。
CREATE OR REPLACE FUNCTION public.std_deviation(VARIADIC inputs numeric[])
RETURNS numeric AS
$BODY$
DECLARE
result numeric;
BEGIN
with foo as (
select unnest (inputs) as bar
)
select stddev (bar)
into result
from foo;
return result;
end
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
答案 2 :(得分:0)
事实证明,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';