Postgres (Amazon RDS) 如何计算加权平均值
Postgres (Amazon RDS) how to calculate weighted average
我正在使用 Amazon RDS Postgres 数据库 (9.4.4),我想计算一些数据的加权平均值。
我找到了以下看起来非常适合这项工作的扩展。
https://github.com/Kozea/weighted_mean
但是我现在不确定如何安装扩展,因为我的初步研究表明只允许 'supported' 个扩展。
我有哪些选项可以使用此扩展程序。我不想重新发明轮子,而且我不熟悉在 Postgres 中安装任何类型的 function/extension。
谢谢
为什么你不发出像这样的简单查询:
select
case when sum(quantity) = 0 then
0
else
sum(unitprice * quantity) / sum(quantity)
end
from sales;
当然你需要更改字段(单价,数量)
为了注册新的自定义扩展,您需要将适当的脚本添加到 Postgres 安装的 contrib
目录中。 AWS 不允许 允许您进行这种精细控制。
长话短说,您无法向 Amazon RDS 服务添加任何自定义扩展(除了 link you provided or from pg_available_extensions
视图中指定的扩展)。
这是使用 DBaaS(数据库即服务)解决方案的缺点之一。
SUM(value*weight)/SUM(weight)
答案很好,但是如果你需要经常重复使用它,创建一个聚合函数会更方便。
CREATE FUNCTION avg_weighted_step(state numeric[], value numeric, weight numeric)
RETURNS numeric[]
LANGUAGE plpgsql
AS $$
BEGIN
RETURN array[state[1] + value*weight, state[2] + weight];
END;
$$ IMMUTABLE;
CREATE FUNCTION avg_weighted_finalizer(state numeric[])
RETURNS numeric
LANGUAGE plpgsql
AS $$
BEGIN
IF state[2] = 0 THEN
RETURN null;
END IF;
RETURN state[1]/state[2];
END;
$$ IMMUTABLE;
CREATE AGGREGATE avg_weighted(value numeric, weight numeric) (
sfunc = avg_weighted_step,
stype = numeric[],
finalfunc = avg_weighted_finalizer,
initcond = '{0,0}' );
用法示例:
$ table tmp;
v w
-- -
1 2
10 1
(2 rows)
$ select avg_weighted(v, w) from tmp;
avg_weighted
------------------
4.0000000000000000
(1 row)
$ select avg_weighted(v, w) from tmp where v is null;
avg_weighted
------------
∅
(1 row)
我正在使用 Amazon RDS Postgres 数据库 (9.4.4),我想计算一些数据的加权平均值。
我找到了以下看起来非常适合这项工作的扩展。 https://github.com/Kozea/weighted_mean
但是我现在不确定如何安装扩展,因为我的初步研究表明只允许 'supported' 个扩展。
我有哪些选项可以使用此扩展程序。我不想重新发明轮子,而且我不熟悉在 Postgres 中安装任何类型的 function/extension。
谢谢
为什么你不发出像这样的简单查询:
select
case when sum(quantity) = 0 then
0
else
sum(unitprice * quantity) / sum(quantity)
end
from sales;
当然你需要更改字段(单价,数量)
为了注册新的自定义扩展,您需要将适当的脚本添加到 Postgres 安装的 contrib
目录中。 AWS 不允许 允许您进行这种精细控制。
长话短说,您无法向 Amazon RDS 服务添加任何自定义扩展(除了 link you provided or from pg_available_extensions
视图中指定的扩展)。
这是使用 DBaaS(数据库即服务)解决方案的缺点之一。
SUM(value*weight)/SUM(weight)
答案很好,但是如果你需要经常重复使用它,创建一个聚合函数会更方便。
CREATE FUNCTION avg_weighted_step(state numeric[], value numeric, weight numeric)
RETURNS numeric[]
LANGUAGE plpgsql
AS $$
BEGIN
RETURN array[state[1] + value*weight, state[2] + weight];
END;
$$ IMMUTABLE;
CREATE FUNCTION avg_weighted_finalizer(state numeric[])
RETURNS numeric
LANGUAGE plpgsql
AS $$
BEGIN
IF state[2] = 0 THEN
RETURN null;
END IF;
RETURN state[1]/state[2];
END;
$$ IMMUTABLE;
CREATE AGGREGATE avg_weighted(value numeric, weight numeric) (
sfunc = avg_weighted_step,
stype = numeric[],
finalfunc = avg_weighted_finalizer,
initcond = '{0,0}' );
用法示例:
$ table tmp;
v w
-- -
1 2
10 1
(2 rows)
$ select avg_weighted(v, w) from tmp;
avg_weighted
------------------
4.0000000000000000
(1 row)
$ select avg_weighted(v, w) from tmp where v is null;
avg_weighted
------------
∅
(1 row)