如何在PostgreSQL中转置二维数组

时间:2017-05-26 20:10:19

标签: sql arrays postgresql transpose

create table matrices(
 matrix text[][] not null);

它的价值:

 insert into Matrices values
    (array[ ['1','2','3'],
            ['4','5','6'] ]),
    (array[ ['a','b','c'],
            ['d','e','f'] ]);

我如何编写SQL来转置每个数组,以便结果如下:

   matrix
-------------
{{1,4},{2,5},{3,6}}
{{a,d},{b,e},{c,d}}
(2 rows)

3 个答案:

答案 0 :(得分:1)

有点冗长,但这里是

SELECT array_agg(v ORDER BY j) matrix  FROM (
    SELECT rn, j, array_agg(v ORDER BY i) AS v FROM (
        SELECT rn, i, j, matrix[i][j] AS v FROM (
            SELECT generate_subscripts(matrix, 2) j, q.* FROM (
                SELECT ROW_NUMBER() OVER () AS rn,
                       generate_subscripts(matrix, 1) AS i, 
                       matrix                
                  FROM matrices
            ) q
        ) r
    ) s
     GROUP BY rn, j
) t
 GROUP BY rn
 ORDER BY rn;

这是dbfiddle演示

或创建一个功能

CREATE OR REPLACE FUNCTION transpose_2d(anyarray)
RETURNS anyarray AS $$
SELECT array_agg(v ORDER BY j) matrix  FROM (
    SELECT j, array_agg(v ORDER BY i) AS v FROM (
        SELECT i, j, $1[i][j] AS v FROM (
            SELECT generate_subscripts($1, 2) j, q.* FROM (
                SELECT generate_subscripts($1, 1) AS i, $1
            ) q
        ) r
    ) s
     GROUP BY j
) t
$$ LANGUAGE sql IMMUTABLE;

用法

SELECT transpose_2d(matrix) 
  FROM matrices;

这是dbfiddle演示

输出(在两种情况下):

       matrix
---------------------
 {{1,4},{2,5},{3,6}}
 {{a,d},{b,e},{c,f}}
(2 rows)

答案 1 :(得分:0)

稍微简化一下:

create or replace function array_transpose(arr anyarray)
returns anyarray as
$f$
    select array_agg(
            (select array_agg(arr[i][j] order by i)
                from generate_subscripts(arr, 1) as i)
            order by j
           )
        from generate_subscripts(arr, 2) as j
$f$ 
language sql immutable;

答案 2 :(得分:0)

这也有效

SELECT
  ARRAY(
    SELECT (
      ARRAY (
        SELECT matrix[j][s]
        FROM ( SELECT generate_subscripts(matrix, 1) AS j ) foo
      )
    ) 
    FROM ( SELECT generate_subscripts(matrix, 2) AS s ) bar
  ) as matrix
FROM matrices m