2017-05-26 178 views
2

一個表如何轉二維陣列中的PostgreSQL

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) 

回答

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) 
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;