vol*_*ron 5 sql arrays postgresql unnest
给定:{{1,"a"},{2,"b"},{3,"c"}}
期望:
foo | bar
-----+------
1 | a
2 | b
3 | c
Run Code Online (Sandbox Code Playgroud)
您可以通过以下查询获得预期结果;但是,最好有一些可以随数组大小缩放的东西。
SELECT arr[subscript][1] as foo, arr[subscript][2] as bar
FROM ( select generate_subscripts(arr,1) as subscript, arr
from (select '{{1,"a"},{2,"b"},{3,"c"}}'::text[][] as arr) input
) sub;
Run Code Online (Sandbox Code Playgroud)
不确定你所说的“最好有一些可以随着数组大小缩放的东西”到底是什么意思。当然,随着内部数组大小的增长,您不能将额外的列添加到结果集中,因为 postgresql 必须在执行之前(因此在开始读取字符串之前)知道查询的确切列。
但我想建议将字符串转换为矩阵的正常关系表示:
select i, j, arr[i][j] a_i_j from (
select i, generate_subscripts(arr,2) as j, arr from (
select generate_subscripts(arr,1) as i, arr
from (select ('{{1,"a",11},{2,"b",22},{3,"c",33},{4,"d",44}}'::text[][]) arr) input
) sub_i
) sub_j
Run Code Online (Sandbox Code Playgroud)
这使:
i | j | a_i_j
--+---+------
1 | 1 | 1
1 | 2 | a
1 | 3 | 11
2 | 1 | 2
2 | 2 | b
2 | 3 | 22
3 | 1 | 3
3 | 2 | c
3 | 3 | 33
4 | 1 | 4
4 | 2 | d
4 | 3 | 44
Run Code Online (Sandbox Code Playgroud)
我认为这样的结果对于进一步的数据处理可能相当有用。
当然,这样的查询只能处理具有预定义维度数的数组,但可以更改其所有维度的所有数组大小,而无需重写查询,因此这是更灵活的方法。
添加:是的,使用with recursive它可以构建类似的查询,能够处理任意维度的数组。尽管如此,无法克服关系数据模型的限制 - 必须在查询解析时定义精确的列集,并且无法将其延迟到执行时。因此,我们被迫使用另一个数组将所有索引存储在一列中。
以下查询从任意多维数组中提取所有元素及其从零开始的索引(存储在另一个一维数组中):
with recursive extract_index(k,idx,elem,arr,n) as (
select (row_number() over())-1 k, idx, elem, arr, n from (
select array[]::bigint[] idx, unnest(arr) elem, arr, array_ndims(arr) n
from ( select '{{{1,"a"},{11,111}},{{2,"b"},{22,222}},{{3,"c"},{33,333}},{{4,"d"},{44,444}}}'::text[] arr ) input
) plain_indexed
union all
select k/array_length(arr,n)::bigint k, array_prepend(k%array_length(arr,2),idx) idx, elem, arr, n-1 n
from extract_index
where n!=1
)
select array_prepend(k,idx) idx, elem from extract_index where n=1
Run Code Online (Sandbox Code Playgroud)
这使:
idx | elem
--------+-----
{0,0,0} | 1
{0,0,1} | a
{0,1,0} | 11
{0,1,1} | 111
{1,0,0} | 2
{1,0,1} | b
{1,1,0} | 22
{1,1,1} | 222
{2,0,0} | 3
{2,0,1} | c
{2,1,0} | 33
{2,1,1} | 333
{3,0,0} | 4
{3,0,1} | d
{3,1,0} | 44
{3,1,1} | 444
Run Code Online (Sandbox Code Playgroud)
从形式上来说,这似乎证明了这个概念,但我想知道它能有什么真正的实际用途:)