如何使用postgreSQL访问数组内部索引?

Pet*_*uss 5 arrays postgresql indexing

这是我(也许通常适合你)的非优化解决方案:

使用非优化内部函数的PG问题的解决方法:

CREATE FUNCTION unnest_with_idx(anyarray)
RETURNS TABLE(idx integer, val anyelement) AS
$$ 
   SELECT generate_series(1,array_upper($1,1)) as idx, unnest($1) as val;
$$ LANGUAGE SQL IMMUTABLE;
Run Code Online (Sandbox Code Playgroud)

测试:

SELECT idx,val from unnest_with_idx(array[1,20,3,5]) as t;
Run Code Online (Sandbox Code Playgroud)

但是,正如我所说,非优化.我不敢相信(!!)PostgreSQL没有数组的内部索引......?但在这种情况下,问题是如何直接访问这个GIN类内部计数器的指数?

注1:上面的解决方案和问题与" 如何通过数组的每个元素创建索引? "不同.也可以与" Can PostgreSQL索引数组列? "不同,因为该函数用于隔离数组,而不是用于数组字段的表索引.


NOTE2(在答案后编辑):"数组索引"(更常用的术语)或"数组下标"或"数组计数器"是我们可以在语义路径中使用的术语,用于将"内部计数器",累加器引用到下一个数组项目.我看到没有PostgreSQL命令提供对此计数器的直接访问.作为generate_series()函数,generate_subscripts()函数是序列生成器,并且性能(最好但是)接近相同.通过其他手工row_number()功能提供了对"内部行计数器"的直接访问,但它是关于行,而不是关于数组,不幸的是性能更差.

Erw*_*ter 6

PostgreSQL 确实提供了生成数组下标的专用函数:

WITH   x(a) AS ( VALUES ('{1,20,3,5}'::int[]) )
SELECT generate_subscripts(a, 1) AS idx
      ,unnest(a) AS val
FROM   x;
Run Code Online (Sandbox Code Playgroud)

实际上,它与@Frank的查询几乎完全相同,只是没有子查询.
此外,它适用于不能开头的下标1.

这两种解决方案都只适用于一维数组!(可以轻松扩展到多个维度.)

功能:

CREATE OR REPLACE FUNCTION unnest_with_idx(anyarray) 
RETURNS TABLE(idx integer, val anyelement) LANGUAGE SQL IMMUTABLE AS
$func$
  SELECT generate_subscripts($1, 1), unnest($1);
$func$;
Run Code Online (Sandbox Code Playgroud)

呼叫:

SELECT * FROM unnest_with_idx('{1,20,3,5}'::int[]);
Run Code Online (Sandbox Code Playgroud)

还要考虑:

SELECT * FROM unnest_with_idx('[4:7]={1,20,3,5}'::int[]);
Run Code Online (Sandbox Code Playgroud)

有关此相关问题中的数组下标的更多信息.

如果你真的想要标准化的下标(从1开始),我会使用:

SELECT generate_series(1, array_length($1,1)) ...
Run Code Online (Sandbox Code Playgroud)

这几乎就是你已经存在的查询,array_length()而不是array_upper()- 这会因非标准下标而失败.

性能

我对1000 int的数组进行了快速测试,目前为止所有查询都在这里.它们都执行大约相同的(~3.5 ms) - 除了row_number()子查询(~7,5 ms) - 正如预期的那样,因为子查询.

更新:Postgres 9.4+

除非您使用非标准索引下标,否则请使用new WITH ORDINALITY: