相关疑难解决方法(0)

带有元素编号的PostgreSQL unnest()

当我有一个具有分隔值的列时,我可以使用该unnest()函数:

myTable
id | elements
---+------------
1  |ab,cd,efg,hi
2  |jk,lm,no,pq
3  |rstuv,wxyz

select id, unnest(string_to_array(elements, ',')) AS elem
from myTable

id | elem
---+-----
1  | ab
1  | cd
1  | efg
1  | hi
2  | jk
...
Run Code Online (Sandbox Code Playgroud)

我如何包含元素编号?即:

id | elem | nr
---+------+---
1  | ab   | 1
1  | cd   | 2
1  | efg  | 3
1  | hi   | 4
2  | jk   | 1
...
Run Code Online (Sandbox Code Playgroud)

我想要源字符串中每个元素的原始位置.我试着窗口函数(row_number(), …

sql arrays postgresql window-functions set-returning-functions

69
推荐指数
3
解决办法
8万
查看次数

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

PostgreSQL可以在任何地方开始使用数组下标.
考虑这个创建一个包含3个元素的数组的示例,其中包含5到7的下标:

SELECT ('[5:7]={1,2,3}'::int[]);
Run Code Online (Sandbox Code Playgroud)

返回:

[5:7]={1,2,3}
Run Code Online (Sandbox Code Playgroud)

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

SELECT ('[5:7]={1,2,3}'::int[])[5];
Run Code Online (Sandbox Code Playgroud)

我想规范化 任何给定的1维数组以从数组下标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)]
Run Code Online (Sandbox Code Playgroud)

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

WITH x(a) AS (
    SELECT '[5:7]={1,2,3}'::int[]
    )
SELECT a[array_lower(a, 1):array_upper(a, 1)]
FROM   x
Run Code Online (Sandbox Code Playgroud)

你知道更简单/更快或更优雅的方式吗?


基准

为了测试性能,我提出了这个快速基准测试.
表有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 …
Run Code Online (Sandbox Code Playgroud)

arrays postgresql performance

7
推荐指数
2
解决办法
1242
查看次数