先前行数组的累积数组?

Posted

技术标签:

【中文标题】先前行数组的累积数组?【英文标题】: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 提供的答案在我看来要好得多。你有什么理由接受我的吗? 【参考方案1】:

这取决于您使用什么。似乎您的基表包含文本数组text[]

您可以使用任何聚合函数作为窗口函数。 Per documentation:

除了这些函数之外,任何内置或用户定义的聚合 函数可以作为窗口函数使用

array_agg(),但它作用于标量类型,作用于数组类型。 但您可以轻松create your own aggregate function。

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

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 触发器。

【讨论】:

以上是关于先前行数组的累积数组?的主要内容,如果未能解决你的问题,请参考以下文章

Google Sheets ArrayFormula - 前行的平均值

用于查看所有先前行的 SQL 语句

根据给定日期的条件及其先前行操作列检索最新行

对每一行应用一个函数,其中函数使用 DataFrame 的所有先前行

如何引用 BigQuery SQL 中先前行的列值,以便执行操作或计算?

使用 T-SQL 根据先前行的值逐行更新表