在RDBM中有效地保存可求数组值

时间:2017-01-17 13:32:49

标签: arrays postgresql aggregate

我有一个数据集,我们跟踪每百分比的参与度(因此8人活跃在38%,7人活跃在39%,等等)。这给出了一个包含100个值的数组,用整数填充。

我需要将它存储在postgres表中。唯一/主要要求是我需要能够对每个索引的值求和以形成新数组。例如:

Row 1: [5, 3, 5, ... 7]
Row 2: [2, 5, 3, ... 1]
Sum:   [7, 8, 8, ... 8]

保存这些内容的天真方法是100个单独的(BIG)INT列,这样您就可以在多行中对每列的值求和。但是,这使得表格非常宽(并且似乎不是最有效的方法)。我查看了(BIG)INT[100]列,但我似乎无法找到一种好的本地方法来对值进行求和。 json(b)列(使用本机JSON数组)也是如此。

我忽略了什么吗?有没有一个好的,有效的方法来做到这一点,而不是完全膨胀表?

2 个答案:

答案 0 :(得分:1)

使用unnest() with ordinality的解决方案:

with the_table(intarr) as (
    values 
        (array[1, 2, 3, 4]), 
        (array[1, 2, 3, 4]), 
        (array[1, 2, 3, 4])
)

select array_agg(sum order by ordinality)
from (
    select ordinality, sum(unnest)
    from the_table,
    lateral unnest(intarr) with ordinality
    group by 1
    ) s;

 array_agg  
------------
 {3,6,9,12}
(1 row)     

答案 1 :(得分:0)

以下是一种似乎有效的方法:

select array_agg(sum_aval order by ind)
from (select ind, sum(aval) sum_aval
      from (select id, unnest(a) as aval, generate_series(1, 3) as ind
            from (values (1, array[1, 2, 3]), (2, array[3, 4, 5])) v(id, a)
           ) x
      group by ind
     ) x;

也就是说,不需要数组使用generate_series()为它们生成索引。然后,您可以在索引级别进行聚合,然后重新组合成一个数组(使用两个单独的聚合)。