我可以使用什么有效的函数来增加数组中元素的位置?
例如,如果我有一个数组:
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”。
答案 0 :(得分:3)
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?
generate_subscripts()
和array_fill()
上的手册。
注意:这适用于实际的数组索引,它可能与Postgres中的序数数组位置不同。您可能对@ Daniel的方法感兴趣,以及#34;规范化"数组索引:
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;