Pairwise array sum aggregate function?

后端 未结 2 1678
你的背包
你的背包 2020-12-31 14:53

I have a table with arrays as one column, and I want to sum the array elements together:

> create table regres(a int[] not null);
> insert into regres          


        
相关标签:
2条回答
  • 2020-12-31 15:12

    A general solution in Postgres 9.3+ for any number of arrays with any number of elements.
    Individual elements or the the whole array can be NULL, too:

    SELECT ARRAY (
       SELECT sum(arr[rn])
       FROM  tbl t
           , generate_subscripts(t.arr, 1) AS rn
       GROUP BY rn
       ORDER BY rn
       );
    

    This makes use of an implicit LATERAL JOIN (Postgres 9.3+).
    With your example values:

    SELECT ARRAY (
       SELECT sum(arr[rn])
       FROM  (
          VALUES
            ('{1,2,3}'::int[])
           ,('{9,12,13}')
          ) t(arr)
        , generate_subscripts(t.arr, 1) AS rn
       GROUP BY rn
       ORDER BY rn
       );
    

    Non-trivial example:

    SELECT ARRAY (
       SELECT sum(arr[rn])
       FROM  (
          VALUES
            ('{1,2,3}'::int[])
           ,('{9,12,13}')
           ,('{1,1,1, 33}')
           ,('{NULL,NULL}')
           ,(NULL)
          ) t(arr)
        , generate_subscripts(t.arr, 1) AS rn
       GROUP BY rn
       ORDER BY rn
       );
    

    Simpler in 9.4+ using WITH ORDINALITY

    SELECT ARRAY (
       SELECT sum(elem)
       FROM  tbl t
           , unnest(t.arr) WITH ORDINALITY x(elem, rn)
       GROUP BY rn
       ORDER BY rn
       )
    

    Postgres 9.1

    SELECT ARRAY (
       SELECT sum(arr[rn])
       FROM  (
          SELECT arr, generate_subscripts(arr, 1) AS rn
          FROM   tbl t
          ) sub
       GROUP BY rn
       ORDER BY rn
       );
    

    The same works in later versions, but set-returning functions in the SELECT list are not standard SQL and frowned upon by some. So use above alternatives with current Postgres.

    SQL Fiddle.

    Related answers with more explanation:

    • PostgreSQL unnest() with element number
    • Is there something like a zip() function in PostgreSQL that combines two arrays?
    0 讨论(0)
  • 2020-12-31 15:17

    If you need better performances and can install Postgres extensions, the agg_for_vecs C extension provides a vec_to_sum function that should meet your need. It also offers various aggregate functions like min, max, avg, and var_samp that operate on arrays instead of scalars.

    0 讨论(0)
提交回复
热议问题