在 Postgresql 中取消多维数组的一层嵌套

Rot*_*eti 5 sql arrays postgresql

假设我有这个三维数组:

ARRAY[[['abc', 'def'], ['ghi', 'jkl']], [['mno', 'pqr'], ['stu', 'vwx']]]
Run Code Online (Sandbox Code Playgroud)

我怎样才能摆脱{{abc,def},{ghi,jkl}}它?

如果我尝试:

SELECT (ARRAY[[['abc', 'def'], ['ghi', 'jkl']], [['mno', 'pqr'], ['stu', 'vwx']]])[1:1]
Run Code Online (Sandbox Code Playgroud)

我明白了{{{abc,def},{ghi,jkl}}},但我需要{{abc,def},{ghi,jkl}}

类似问题的答案可以解决二维数组的问题,例如这个,但这些答案不适用于 n 维数组。

这是一个非常基本的任务,但在 PostgreSQL 中似乎相当棘手。

Jer*_*emy 1

我真的希望有人可以提供一种更直接的方法来做到这一点,但这是我的镜头:

  with my_array as 
      (select ARRAY[[['abc', 'def'], ['ghi', 'jkl']], [['mno', 'pqr'], ['stu', 'vwx']]] as arr),
  deconstructed_array as (
    select a.elem, a.nr, x, y, z
    FROM my_array, unnest(arr) WITH ordinality as a(elem, nr) 
    JOIN (
        SELECT x, y, z, row_number() over (ORDER BY x, y, z) as row
        FROM my_array,
        generate_series(array_lower(arr, 1), array_upper(arr, 1)) g1(x),
        generate_series(array_lower(arr, 2), array_upper(arr, 2)) g2(y),
        generate_series(array_lower(arr, 3), array_upper(arr, 3)) g3(z)
    ) array_dims ON nr = row
)
select array_agg(elems) FROM (
   select array_agg(elem) as elems, x, y
   FROM deconstructed_array GROUP BY x, y
) first_level 
WHERE x = 1
group by x
;
       array_agg
-----------------------
 {{abc,def},{ghi,jkl}}
(1 row)
Run Code Online (Sandbox Code Playgroud)

说明:我们使用generate_series将数组的各个维度与未嵌套的行关联起来。不幸的是,我们需要知道在这种情况下这是一个三维数组,但每个数组的长度并不重要。第二个 CTE 的输出如下所示:

 elem | nr | x | y | z
------+----+---+---+---
 abc  |  1 | 1 | 1 | 1
 def  |  2 | 1 | 1 | 2
 ghi  |  3 | 1 | 2 | 1
 jkl  |  4 | 1 | 2 | 2
 mno  |  5 | 2 | 1 | 1
 pqr  |  6 | 2 | 1 | 2
 stu  |  7 | 2 | 2 | 1
 vwx  |  8 | 2 | 2 | 2
Run Code Online (Sandbox Code Playgroud)

从那里,我们只需使用 array_agg 将数组重新组合在一起。