select arr[array_lower(arr,1)+1 : array_upper(arr,1)-1] as ok1
, trim_array(arr[array_lower(arr,1)+1 :],1) as ok2
, arr[2 : ] as wrong1
, arr[2 : 3] as wrong2
, arr[ :array_length(arr,1)-1] as wrong3
, arr[2 :-2] as wrong4
, (arr[2:])[:-2] as wrong5
from (SELECT '[50:53]={50,51,52,53}'::int[]) as your(arr);
trim_array()从 PostgreSQL 14 开始存在:
Postgres 数组索引并非严格基于 1,这就是它提供
array_lower()
、array_upper()
、trim_array()
的原因。[2:]
切片不会删除第一个元素,它会删除索引 2 之前的所有元素,这些元素可能有很多、一个或没有:db<>fiddle 上的演示
在这个数组中,第一个索引是
50
,而不是1
。使用array_length()
获取最后一个元素的索引也不可靠:它的长度是4
但最后一个索引是53
。你甚至可能会遇到负指数:
在这种情况下,所有使用长度和正索引的切片和下标都会清除整个内容。
该示例还说明了为什么负下标不从末尾向后计数 - 它们完全可以作为常规索引,而无需翻转顺序。您可能期望的
[2:-2]
和(arr[2:])[:-2]
将获得一个空数组:第一部分会删除索引以下的所有内容2
,其中包括具有负索引的位置的所有元素,然后第二部分仅要求那些直到的元素-2
,所有这些元素您刚刚都删除了。您可以使用数组长度函数来获取数组长度: