【问题标题】:Unnest multi dimensional array by one level in Postgresql在 Postgresql 中一级取消嵌套多维数组
【发布时间】:2019-05-11 03:46:21
【问题描述】:

假设我有这个三维数组:

ARRAY[[['abc', 'def'], ['ghi', 'jkl']], [['mno', 'pqr'], ['stu', 'vwx']]]

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

如果我尝试:

SELECT (ARRAY[[['abc', 'def'], ['ghi', 'jkl']], [['mno', 'pqr'], ['stu', 'vwx']]])[1:1]

我得到{{{abc,def},{ghi,jkl}}},但我需要{{abc,def},{ghi,jkl}}

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

这是一项基本任务,但在 PostgreSQL 中似乎相当棘手。

【问题讨论】:

    标签: sql arrays postgresql


    【解决方案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)
    

    说明: 我们使用 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
    

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

    【讨论】:

      猜你喜欢
      • 2022-01-13
      • 2021-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多