如何在PostgreSQL中获取数组的最后一个元素?

35
PostgreSQL数组文档提供了一个使用[-1]来访问数组最后一个元素的示例;然而,当SELECT arr[2:3];产生 {5,9}时,arr[2:-1]的结果是{}
如何在PostgreSQL中获取数组的最后一个元素?
编辑:Windows,PostgreSQL v9.2.1
4个回答

63

要获取数组"arr"的最后一个元素,可以使用:

SELECT arr[array_upper(arr, 1)];

34

我认为你误解了这个例子。PostgreSQL 数组不必从 1 到 n 进行索引,那只是默认值

默认情况下,PostgreSQL 使用一个基于 1 的编号约定来处理数组,即一个由 n 个元素组成的数组以 array[1] 开始,以 array[n] 结束。

你所看到的例子是这样的:

SELECT f1[1][-2][3] AS e1, f1[1][-1][5] AS e2
 FROM (SELECT '[1:1][-2:-1][3:5]={{{1,2,3},{4,5,6}}}'::int[] AS f1) AS ss;

但是这些负数并不像Perl等语言一样从数组的末尾索引。在 FROM (SELECT ... 部分,它们指定了起始和结束索引,因此f1[1][-1][5] 中的-1只是普通的索引。考虑这个array_dims 的结果:

=> SELECT array_dims('[1:1][-2:-1][3:5]={{{1,2,3},{4,5,6}}}'::int[]);
    array_dims     
-------------------
 [1:1][-2:-1][3:5]
如果您使用默认的以1为起始索引的数组,则可以使用简单的arr[array_length(arr, 1)]来获取最后一个元素。如果您没有使用默认的[1:n]数组,则需要使用array_lowerarray_upper进行操作,以获取第一个和最后一个元素;或者根据情况,您可能可以使用unnest将数组解包,然后将数组视为行集进行操作。

8

如果有人正在使用Postgre 9.5,文档中写道:

-> int

获取JSON数组元素(从零开始索引,负整数从末尾计数)

所以这对我起作用:

to_json(arr)->-1

仅适用于arrjson类型。对于PostgreSQL数组类型不起作用。 - Julian Mehnle
1
在我的情况下,array_agg(id) 运行良好。 - Dorian
这个答案帮助我想出了这个解决方案:array_to_json(ARRAY(SELECT...))->-1 - TheAddonDepot

2

我有一个情况,我不想这样做:

  • 两次引用数组 如此建议(因为数组是复杂的数组表达式)
  • 使用 JSON 解决方法 如此建议(因为数组可以是任何非 JSON 兼容类型)

所以,另一个选择是使用 UNNEST .. WITH ORDINALITY

SELECT
  a,
  (
    SELECT v 
    FROM unnest(a) 
    WITH ORDINALITY AS t (v, o) 
    ORDER BY o DESC 
    LIMIT 1
  )
FROM (VALUES (ARRAY[1, 3, 2])) AS t (a)

生成:

|a      |v  |
|-------|---|
|{1,3,2}|2  |

当然,假设没有针对WITH ORDINALITYLIMIT 1组合的聪明优化,这将在最坏情况下以O(N log N)(由于排序)找到最后一个数组元素,而不是O(1),但有时候数组足够小,有时候也没有其他方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接