7

PostgreSQL 可以使用从任何位置开始的数组下标
考虑这个例子,它创建了一个包含 3 个元素的数组,下标从 5 到 7:

SELECT '[5:7]={1,2,3}'::int[];

回报:

[5:7]={1,2,3}

我们得到下标的第一个元素5

SELECT ('[5:7]={1,2,3}'::int[])[5];

我想标准化一维数组以从数组下标 1 开始
我能想到的最好的:

SELECT ('[5:7]={1,2,3}'::int[])[array_lower('[5:7]={1,2,3}'::int[], 1):array_upper('[5:7]={1,2,3}'::int[], 1)]

同样,更容易阅读:

WITH   cte(a) AS (SELECT '[5:7]={1,2,3}'::int[])
SELECT a[array_lower(a, 1):array_upper(a, 1)]
FROM   cte;

您知道更简单/更快或至少更优雅的方式吗?

在 Postgres 9.5 上使用旧解决方案进行基准测试

db<>在这里摆弄

基准包括 Postgres 14 上的新解决方案

db<>在这里摆弄

4

3 回答 3

6

有一个更简单的方法是丑陋的,但我相信在技术上是正确的:从数组中提取最大可能的切片,而不是具有计算边界的精确切片。它避免了两个函数调用。

例子:

select ('[5:7]={1,2,3}'::int[])[-2147483648:2147483647];

结果是:

  整数4   
---------
 {1,2,3}
于 2012-08-17T19:49:36.313 回答
6

最终,Postgres 9.6出现了一些更优雅的东西手册:

可以省略切片说明符的lower-bound和/或 upper-bound;缺少的界限被数组下标的下限或上限替换。例如:

所以现在很简单:

SELECT my_arr[:];

使用我的示例数组文字,您需要用括号括起来以使语法明确::

SELECT ('[5:7]={1,2,3}'::int[])[:];

与使用硬编码最大数组下标的 Daniel 解决方案的性能大致相同——这仍然是 Postgres 9.5 或更早版本的方式。

于 2017-06-09T02:12:19.640 回答
3

不确定这是否已经涵盖,但是:

SELECT array_agg(v) FROM unnest('[5:7]={1,2,3}'::int[]) AS a(v);

为了测试性能,我必须id在测试表上添加列。减缓。

于 2012-08-17T21:57:35.810 回答