前一行数组的累积数组?

时间:2014-03-19 05:35:51

标签: sql arrays postgresql window-functions

是否存在将先前数组合并为累积数组的查询,这将导致:

id array_field   c_array
---------------------------------------------
1  {one,two}     {one,two}
2  {three}       {one,two,three}
3  {four,five}   {one,two,three,four,five}
4  {six}         {one,two,three,four,five,six}

3 个答案:

答案 0 :(得分:2)

这取决于你的工作。好像您的基表包含文本数组text[]

  

除了这些功能外,还有任何内置或用户定义的聚合   函数可以用作窗口函数

要聚合数组类型,请创建此聚合函数:

CREATE AGGREGATE array_agg_mult (anyarray)  (
    SFUNC     = array_cat
   ,STYPE     = anyarray
   ,INITCOND  = '{}'
);

此相关答案的详情:
Selecting data into a Postgres array

现在,这项工作非常简单:

SELECT array_agg_mult(array_field) OVER (ORDER BY id) AS result_array
FROM   tbl

由于聚合是为polymorphic types定义的,因此适用于任何数组类型,而不只是text[]

SQL Fiddle包括列表中文本表示的替代解决方案。

答案 1 :(得分:1)

您可以使用recursive CTE

SQLFiddle

数据:

-- drop table if exists sample_data;
create table sample_data (id int, arr varchar[]);

insert into sample_data
  values
    (1,ARRAY['One','Two','Three']),
    (2,ARRAY['Four','Six']),    
    (3,ARRAY['Seven']);

查询:

with recursive cte as (
  select 
    id, arr, arr as merged_arr 
  from 
    sample_data
  where
    id = 1

  union all

  select 
    sd.id, sd.arr, cte.merged_arr || sd.arr
  from
    cte
    join sample_data sd on (cte.id + 1  = sd.id)
)

select * from cte

结果:

1;{One,Two,Three};{One,Two,Three}
2;{Four,Six};     {One,Two,Three,Four,Six}
3;{Seven};        {One,Two,Three,Four,Six,Seven}

答案 2 :(得分:0)

您需要一个UPDATE,其CTE会引用以前的ID:

WITH prev AS (SELECT id, c_array AS prev_array FROM your_table)
UPDATE your_table
SET c_array = prev_array || array_field
FROM prev
WHERE id = prev.id + 1;

如果你想自动执行此操作,那么你需要一个BEFORE INSERT触发器,并且在触发器功能中你只需执行SELECT c_array || NEW.array_field INTO NEW.c_array FROM your_table WHERE id = NEW.id - 1如果 - 并且只有 - 你自己设置了id。如果id来自序列,那么您需要一个AFTER INSERT触发器,其中包含如上所述的更新。