Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 如何使用postgreSQL访问数组内部索引?_Arrays_Postgresql_Indexing - Fatal编程技术网

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

Arrays 如何使用postgreSQL访问数组内部索引?,arrays,postgresql,indexing,Arrays,Postgresql,Indexing,这是我的(对您来说可能是常见的)非优化的解决方案: 具有非优化内部功能的PG问题的解决方法: CREATE FUNCTION unnest\u with_idx(anyarray) 将表(idx integer,val anyelement)返回为 $$ 选择generate_series(1,array_upper($1,1))作为idx,unnest($1)作为val; $$语言SQL不可变; 测试: 从unnest_中选择idx,val,并将_idx(数组[1,20,3,5])作为t;

这是我的(对您来说可能是常见的)非优化的解决方案:

具有非优化内部功能的PG问题的解决方法:

CREATE FUNCTION unnest\u with_idx(anyarray)
将表(idx integer,val anyelement)返回为
$$ 
选择generate_series(1,array_upper($1,1))作为idx,unnest($1)作为val;
$$语言SQL不可变;
测试:

从unnest_中选择idx,val,并将_idx(数组[1,20,3,5])作为t;
但是,正如我所说,非优化。我不敢相信(!!)PostgreSQL没有数组的内部索引?但在这种情况下,问题是如何直接访问这个索引,内部计数器在哪里

注1:上述答案和问题与“”不同。也与“”不同,因为该函数用于独立数组,而不是用于数组字段的表索引


注2(回答后编辑):“数组索引”(更流行的术语)或“数组下标”或“数组计数器”是我们可以在语义路径中使用的术语,用于将“内部计数器”(累加器)引用到下一个数组项。我看到没有PostgreSQL命令提供对该计数器的直接访问。作为
generate_series()
函数,
generate_subscripts()
函数是一个序列生成器,性能(最佳但)几乎相同。另一方面,
row\u number()
函数提供了对“行的内部计数器”的直接访问,但它是关于行的,而不是关于数组的,不幸的是,性能更差。

有效:

然后,将优化函数

CREATE OR REPLACE FUNCTION unnest_with_idx(anyarray) 
RETURNS table(idx integer, val anyelement) AS $$ 
  SELECT (row_number() over())::integer as idx, val
  FROM (SELECT unnest($1)) a(val);
$$ LANGUAGE SQL IMMUTABLE;
PostgreSQL确实为以下各项提供了专用功能:

电话:

还应考虑:

SELECT * FROM unnest_with_idx('[4:7]={1,20,3,5}'::int[]);
有关中数组下标的详细信息

如果您确实想要规范化的下标(从1开始),我会使用:

SELECT generate_series(1, array_length($1,1)) ...
选择generate_series(1,数组长度($1,1))…
这几乎就是您已经进行的查询,只是使用而不是
array\u upper()
——这将在使用非标准下标时失败

演出 我在一个1000 int的数组上运行了一个快速测试,到目前为止,这里提供了所有查询。由于子查询的原因,除了子查询(~7,5 ms)上的
row\u number()
之外,它们的性能都与预期大致相同(~3,5 ms)

更新:Postgres 9.4+ 除非您使用非标准索引下标操作,否则请使用新的具有顺序性的


它保证遵守订单吗?@Quassnoi:我没有测试它,没有排序订单,就没有保证!我正在测试,我认为数组顺序始终保持不变。非常感谢,这就是解决方案。@PeterKrauss:我已经批准了你的编辑。请注意,您也可以回答自己的问题()对不起,我更改了我的“选择答案”:我对行数(150%)、生成下标(109%)和生成下标系列(111%)的百分比时间的基准测试表明,行数是最差的(!),生成下标的速度越快,那么它就接近我需要的“内部数组索引”和优化。谢谢!在生成_级数()之后,有两个新的解决方案。。。什么是最快的:row_number()或generate_subscripts()?@PeterKrauss它取决于您的用例(我的意思是用您的数据测试它)<代码>生成下标()
对我来说更具可读性。但是,当在正常大小的数组上使用时,我不会期望有太大的差异。@PeterKrauss:我添加了一个替代解决方案,以及一个快速性能测试的结果。好的,比较
explain analysis
时间和“SELECT 1,unnest($1)”时间,我的下标为109%,系列为111%,行数为150%。你用
generate_subscripts()
的解决方案是最好的(!),而我用
generate_series()
的解决方案并没有那么错。对读者来说:带有顺序性的
是完美的!在pg9.5中,它也适用于JSON和JSONB数组<代码>从jsonb_数组_元素(“[20,11,3,5]”中选择*::jsonb)并具有顺序性
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$;
SELECT * FROM unnest_with_idx('{1,20,3,5}'::int[]);
SELECT * FROM unnest_with_idx('[4:7]={1,20,3,5}'::int[]);
SELECT generate_series(1, array_length($1,1)) ...