PostgreSQL可以从任何地方开始使用数组下标。
考虑以下示例,该示例创建一个包含3个元素的数组,下标从5到7:
SELECT ('[5:7]={1,2,3}'::int[]);
返回值:
[5:7]={1,2,3}
例如,这意味着您获得了第一个元素
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 x(a) AS (
SELECT '[5:7]={1,2,3}'::int[]
)
SELECT a[array_lower(a, 1):array_upper(a, 1)]
FROM x
您知道更简单/更快或更优雅的方式吗?
基准测试
为了测试性能,我提出了这个快速基准测试。
具有100k行的表,随机长度在1到11之间的简单整数数组:
CREATE TEMP TABLE t (a int[]);
INSERT INTO t -- now with actually varying subscripts
SELECT ('[' || g%10 || ':' || 2*(g%10) || ']={1'
|| repeat(','||g::text, g%10) || '}')::int[]
FROM generate_series(1,100000) g;
EXPLAIN ANALYZE
SELECT
substring(a::text, '{.*$')::int[] -- Total runtime: 949.304 ms
-- a[-2147483648:2147483647] -- Total runtime: 283.877 ms
-- a[array_lower(a, 1):array_upper(a, 1)] -- Total runtime: 311.545 ms
FROM t
因此,是的,@ Daniel的想法稍快一些。
@Kevin的文本转换也可以,但是不会获得很多积分。
还有其他想法吗?
青春有我
牛魔王的故事
一只萌萌小番薯