Sql Postgres中的向量(数组)加法
我有一个包含数值[]的列,所有数值的大小都相同。我想取他们的元素平均值。我的意思是Sql Postgres中的向量(数组)加法,sql,arrays,postgresql,vectorization,Sql,Arrays,Postgresql,Vectorization,我有一个包含数值[]的列,所有数值的大小都相同。我想取他们的元素平均值。我的意思是 {1, 2, 3}, {-1, -2, -3}, and {3, 3, 3} 应该是{1,1,1}。还有一个有趣的问题是如何对这些元素进行求和,尽管我希望一个元素的任何解都是另一个元素的解 注意:数组的长度在单个表中是固定的,但在表之间可能会有所不同。所以我需要一个不假设一定长度的解 我最初的猜测是我应该以某种方式使用unnest,因为应用于数值[]列的unnest会使所有数组变平。所以我想,有一种很好的方法,
{1, 2, 3}, {-1, -2, -3}, and {3, 3, 3}
应该是{1,1,1}。还有一个有趣的问题是如何对这些元素进行求和,尽管我希望一个元素的任何解都是另一个元素的解
注意:数组的长度在单个表中是固定的,但在表之间可能会有所不同。所以我需要一个不假设一定长度的解
我最初的猜测是我应该以某种方式使用unnest,因为应用于数值[]列的unnest会使所有数组变平。所以我想,有一种很好的方法,可以将其与某种窗口函数+分组方式结合使用,来挑选每个数组的各个组件并求和
-- EXAMPLE DATA
CREATE TABLE A
(vector numeric[])
;
INSERT INTO A
VALUES
('{1, 2, 3}'::numeric[])
,('{-1, -2, -3}'::numeric[])
,('{3, 3, 3}'::numeric[])
;
从
从中选择AVGUNESTED,从temp中选择unnestvector作为unnested
编辑:我想我现在更明白这个问题了
这是一个可能的解决方案:我不认为它很优雅,也不确定它会表现得好:
测试数据:
CREATE TABLE A
(vector numeric[], id serial)
;
INSERT INTO A
VALUES
('{1, 2, 3}'::numeric[])
,('{4, 5, 6}'::numeric[])
,('{7, 8, 9}'::numeric[])
;
查询:
select avg(vector[temp.index])
from A as a
join
(select generate_subscripts(vector, 1) as index
, id
from A) as temp on temp.id = a.id
group by temp.index
我自己发现了一个解决方案,这可能就是我将要使用的解决方案 首先,我们可以定义一个用于添加两个向量的函数:
CREATE OR REPLACE FUNCTION vec_add(arr1 numeric[], arr2 numeric[])
RETURNS numeric[] AS
$$
SELECT array_agg(result)
FROM (SELECT tuple.val1 + tuple.val2 AS result
FROM (SELECT UNNEST($1) AS val1
,UNNEST($2) AS val2
,generate_subscripts($1, 1) AS ix) tuple
ORDER BY ix) inn;
$$ LANGUAGE SQL IMMUTABLE STRICT;
和一个乘以常数的函数:
CREATE OR REPLACE FUNCTION vec_mult(arr numeric[], mul numeric)
RETURNS numeric[] AS
$$
SELECT array_agg(result)
FROM (SELECT val * $2 AS result
FROM (SELECT UNNEST($1) AS val
,generate_subscripts($1, 1) as ix) t
ORDER BY ix) inn;
$$ LANGUAGE SQL IMMUTABLE STRICT;
然后我们可以使用PostgreSQL语句CREATE AGGREGATE直接创建vec_sum函数:
CREATE AGGREGATE vec_sum(numeric[]) (
SFUNC = vec_add
,STYPE = numeric[]
);
最后,我们可以发现平均值为:
SELECT vec_mult(vec_sum(vector), 1 / count(vector)) FROM A;
我已经写了一个扩展,用快速C函数做向量加减、乘法、除法和幂运算。你可以找到它,也可以找到它 给定两个数组a和b,你可以说vec_adda,b。您还可以将任意一侧添加到标量,例如vec_adda,5 如果您想要一个求和聚合函数,您可以在中找到它,也可以在中找到
最后,如果要将单个数组的所有元素相加,可以使用。这根本不是所需的。首先,当我需要一个数字[]时,它会返回一个数字。我不确定我是否理解您的预期结果。你在寻找你的数组的平均值吗?是的,根据文章的第三句话。我重读了你的文章。对于输入{1,2,3},{4,5,6},{7,8,9},您期望的是{2,5,8}还是{4,5,6}?{4,5,6}。我将编辑后,使这个例子不含糊的方式。