【问题标题】:Create "counter" array in psql在 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}      |

感谢您的帮助

【问题讨论】:

    标签: sql postgresql psql postgresql-9.4


    【解决方案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)
    ;
    

    【讨论】:

      猜你喜欢
      • 2017-03-20
      • 1970-01-01
      • 2016-01-27
      • 1970-01-01
      • 1970-01-01
      • 2022-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多