加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

arrays – 规范化1维数组的数组下标,使它们从1开始

发布时间:2020-12-13 18:05:12 所属栏目:百科 来源:网络整理
导读:PostgreSQL可以在任何地方开始使用数组下标. 考虑这个创建一个包含3个元素的数组的示例,其中包含5到7的下标: SELECT ('[5:7]={1,2,3}'::int[]); 返回: [5:7]={1,3} 例如,你得到第一个元素的含义 SELECT ('[5:7]={1,3}'::int[])[5]; 我想规范化任何给定的1
PostgreSQL可以在任何地方开始使用数组下标.
考虑这个创建一个包含3个元素的数组的示例,其中包含5到7的下标:
SELECT ('[5:7]={1,2,3}'::int[]);

返回:

[5:7]={1,3}

例如,你得到第一个元素的含义

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

我想规范化任何给定的1维数组以从数组下标1开始.
我能想到的最好的:

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

或者,同样,更容易阅读:

WITH x(a) AS (
    SELECT '[5:7]={1,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)]  -- Total runtime: 311.545 ms
FROM   t

所以,是的,@ Daniel的想法稍快一些.
@Kevin的文字转换也有效,但不会赚很多分.

还有其他想法吗?

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

例:

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

结果是:

  int4   
---------
 {1,3}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读