【问题标题】:Multiply elements in an array according to their position根据位置将数组中的元素相乘
【发布时间】:2014-05-26 23:28:34
【问题描述】:

我可以使用什么有效的函数来按位置增加数组中元素的数量?

例如,如果我有一个数组:

ARRAY[10,20,30,40,50]::INT[]

我希望它变成:

ARRAY[10,20,20,30,30,30,40,40,40,40,50,50,50,50,50]::INT[]

所以我有 1 个“10”、2 个“20”、3 个“30”、4 个“40”和 5 个“50”。

对于数组:

ARRAY[10,20,30,40,10]::INT[]

我希望它变成:

ARRAY[10,20,20,30,30,30,40,40,40,40,10,10,10,10,10]::INT[]

所以我有 6 个“10”、2 个“20”、3 个“30”和 4 个“40”。

【问题讨论】:

    标签: sql arrays postgresql set-returning-functions


    【解决方案1】:
    WITH t AS (SELECT ARRAY[10,20,30,40,50]::INT[] AS arr)   -- variable for demo
    SELECT ARRAY(
       SELECT unnest(array_fill(arr[idx], ARRAY[idx])) AS mult
       FROM  (SELECT arr, generate_subscripts(arr, 1) AS idx FROM t) sub
       );
    

    我会将逻辑包装到一个简单的 IMMUTABLE SQL 函数中:

    CREATE OR REPLACE FUNCTION f_expand_arr(_arr anyarray)
      RETURNS anyarray AS
    $func$
    SELECT ARRAY(
       SELECT unnest(array_fill(_arr[idx], ARRAY[idx]))
       FROM  (SELECT generate_subscripts(_arr, 1) AS idx) sub
       )
    $func$ LANGUAGE sql IMMUTABLE;
    

    由于具有多态参数类型anyarray:
    How to write a function that returns text or integer values?

    ,因此适用于 any 基本类型的数组

    generate_subscripts()array_fill() 的手册。

    注意:这适用于实际的数组索引,它可能与 Postgres 中的序数数组位置不同。您可能对@Daniel 的“标准化”数组索引的方法感兴趣:
    Normalize array subscripts for 1-dimensional array so they start with 1

    即将推出的 Postgres 9.4(目前为测试版)提供 WITH ORDINALITY:
    PostgreSQL unnest() with element number

    允许这种更加优雅和可靠的解决方案:

    CREATE OR REPLACE FUNCTION f_expand_arr(_arr anyarray)
      RETURNS anyarray AS
    $func$
    SELECT ARRAY(
       SELECT unnest(array_fill(a, ARRAY[idx]))
       FROM   unnest(_arr) WITH ORDINALITY AS x (a, idx)
       )
    $func$ LANGUAGE sql IMMUTABLE;
    

    人们可能仍然认为正确的顺序实际上并没有保证。我声称它是...
    Parallel unnest() and sort order in PostgreSQL

    呼叫:

    SELECT f_expand_arr(ARRAY[10,20,30,40,10]::INT[]) AS a2;
    

    或者对于表中的值:

    SELECT f_expand_arr(a) AS a2 FROM t;
    

    SQL Fiddle.

    【讨论】:

      猜你喜欢
      • 2021-08-31
      • 2019-02-28
      • 2022-09-28
      • 2011-06-25
      • 1970-01-01
      • 2021-12-10
      • 1970-01-01
      • 2016-07-24
      相关资源
      最近更新 更多