【问题标题】:Cumulative array from previous rows array?先前行数组的累积数组?
【发布时间】:2014-03-19 05:35:51
【问题描述】:

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

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}

【问题讨论】:

  • 我很高兴您接受了我的回答,但在这种情况下,Erwin 提供的答案在我看来要好得多。你有什么理由接受我的吗?

标签: sql arrays postgresql window-functions


【解决方案1】:

这取决于您使用什么。似乎您的基表包含文本数组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 包括列表中文本表示的替代解决方案。

【讨论】:

    【解决方案2】:

    您可以使用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}
    

    【讨论】:

      【解决方案3】:

      你需要一个 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 触发器。

      【讨论】:

        猜你喜欢
        • 2023-01-20
        • 2021-12-22
        • 1970-01-01
        • 2017-04-02
        • 1970-01-01
        • 1970-01-01
        • 2015-11-27
        • 2022-06-15
        • 2021-11-27
        相关资源
        最近更新 更多