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}。我将编辑后,使这个例子不含糊的方式。