按索引删除数组元素

Faw*_*awn 6 postgresql array

是否可以通过索引删除 Postgres 数组元素?(使用 Postgres 9.3。)

我在文档(http://www.postgresql.org/docs/9.3/static/functions-array.html)中没有看到任何相关内容,但也许我还缺少其他功能?

Erw*_*ter 9

没有我知道的内置函数。在Postgres的9.3+你有类似的功能array_remove(anyarray, anyelement),以(每文档)

从数组中删除所有等于给定值的元素(数组必须是一维的)

要从具有唯一元素的一维数组中删除第三个元素:

SELECT array_remove(arr, arr[3]);
Run Code Online (Sandbox Code Playgroud)

如果不能保证唯一性,上述可能会删除多个元素。您可以改为连接两个数组切片:

Postgres 9.5 或更高版本

SELECT arr[1:2] || arr[4:2147483647] AS arr_without_3rd_elem;
Run Code Online (Sandbox Code Playgroud)

2147483647 只是涵盖所有可能性的最大可能数组下标。适用于至少 8.3 以来的任何版本,可能更多。
关于数组下标:

Postgres 9.3 的旧SQL Fiddle

如果您非常需要此功能,请创建一个函数。我建议使用IMMUTABLE多态SQL 函数。(用 C 实现会快一点。)

CREATE OR REPLACE FUNCTION f_array_remove_elem(anyarray, int)
  RETURNS anyarray LANGUAGE sql IMMUTABLE AS
'SELECT $1[1:$2-1] || $1[$2+1:2147483647]';
Run Code Online (Sandbox Code Playgroud)

称呼:

SELECT f_array_remove_elem('{1,2,3,4,5}'::int[], 4)    AS i
     , f_array_remove_elem('{foo,bar,baz}'::text[], 1) AS t;
Run Code Online (Sandbox Code Playgroud)

结果:

i         | t
----------+-----------
{1,2,3,5} | {bar,baz}
Run Code Online (Sandbox Code Playgroud)

比较复杂...

  • 对于多维数组。
    不能只删除单个元素,维度必须保持同步。因此,您必须定义要准确删除的切片。然后我可能会使用generate_suscripts()取消嵌套数组,删除选定的下标和array_agg()/array_agg_mult()结果。

  • 对于非标准数组下标。
    标准化源中的下标,如链接问题中所示,或使用array_lower()和调整表达式中的下标array_upper()...

Postgres 9.6

.. 为上限和下限引入了简短的表示法(只需省略数字)。我为上面链接的问题添加了一个答案:

现在更简单:

SELECT arr[:2] || arr[4:] AS arr_without_3rd_elem;
Run Code Online (Sandbox Code Playgroud)

功能:

CREATE OR REPLACE FUNCTION f_array_remove_elem(anyarray, int)
  RETURNS anyarray LANGUAGE sql IMMUTABLE AS
'SELECT $1[:$2-1] || $1[$2+1:]';
Run Code Online (Sandbox Code Playgroud)

适用于所有一维数组,包括非标准数组下标。请务必提供要删除的元素的正确数组索引。

dbfiddle在这里

  • 我讨厌没有这样做的核心方法。 (2认同)