在 psql 中创建“计数器”数组

Posted

技术标签:

【中文标题】在 psql 中创建“计数器”数组【英文标题】:Create "counter" array in psql 【发布时间】:2015-10-13 14:57:45 【问题描述】:

我在 postgresql-9.4.2 中有一个带有数组列的表。

create schema test_schema;
create table test_schema.test_table;
(
    array_column int[]
);
insert into test_schema.test_table values
    (ARRAY[5,12,6,2]),
    (ARRAY[51,4,2]),
    (ARRAY[2]),
    (ARRAY[3,16]);

看起来像这样

    | array_column |
    | integer[]    |
--------------------
  1 | 5,12,6,2   |
  2 | 51,4,2     |
  3 | 2          |
  4 | 3,16       |

我想查询这张表,并在我的查询中添加一列,这是一个从 1 计数到数组大小的数组。

我已经弄清楚如何创建一个大小相同的数组,如下所示

select
    array_column,
    array_fill(1,array[array_length(array_column,1)],array[1]) as counter
from
    test_schema.test_table;

返回以下结果

    | array_column | counter    |
    | integer[]    | integer[]  |
---------------------------------
  1 | 5,12,6,2   | 1,1,1,1  |
  2 | 51,4,2     | 1,1,1    |
  3 | 2          | 1        |
  4 | 3,16       | 1,1      |

我打算采用计数器的滚动总和,这会给我想要的结果,但我不知道该怎么做。

这是想要的结果:

    | array_column | counter    |
    | integer[]    | integer[]  |
---------------------------------
  1 | 5,12,6,2   | 1,2,3,4  |
  2 | 51,4,2     | 1,2,3    |
  3 | 2          | 1        |
  4 | 3,16       | 1,2      |

感谢您的帮助

【问题讨论】:

【参考方案1】:

使用函数generate_subscripts(array anyarray, dim int)

select
    array_column,
    array_agg(subscripts) subscripts
from (
    select
        array_column, 
        generate_subscripts(array_column, 1) subscripts
    from
        test_schema.test_table
    ) sub
group by 1;

 array_column | subscripts 
--------------+------------
 2          | 1
 3,16       | 1,2
 5,12,6,2   | 1,2,3,4
 51,4,2     | 1,2,3
(4 rows)

【讨论】:

generate_scripts 更简单,但请注意 OP 可能不想消除 array_column 中的重复项 @ClodoaldoNeto 我不认为这实际上消除了重复,我将第 1 行的值修改为 ARRAY[5,5,5,5] 并且 klin 的答案仍然有效 @Dan 我的意思是行之间的重复数组(2+行具有相同的数组) @ClodoaldoNeto - 实际上应该有一个唯一的字段来分组,或者您可以使用ctid 作为最后的手段。在 Postgres 中没有 generate_scripts @ClodoaldoNeto 啊,我明白了,对此感到抱歉。我没有提到在我的实际实现中我将有一个名为“rowno”的列,类型为“serial”,所以我将简单地按 array_column 和 rowno 分组,这可以解决您提到的问题。【参考方案2】:
select array_column, a
from
    test_table
    cross join lateral (
        select array_agg(a)
        from generate_series(1, array_length(array_column, 1)) s(a)
    ) s(a)
;

【讨论】:

以上是关于在 psql 中创建“计数器”数组的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Java 中的 Iterable 的 for 循环中创建一个计数器并获取计数器变量的值

有没有办法在 iOS 应用程序中创建性能计数器?

如何在高度并发的系统中创建全局计数器

如何在 SQL 2008 R2 的表中创建 AutoCounter 列?

在 XQuery 中更新计数器

Django 查看计数器