Postgres table to two-dimensional array

为君一笑 提交于 2020-12-16 04:16:51

问题


I would like to convert a table with three columns to a two-dimensional array of type integer[][]. There are two columns to indicate each of the two dimensions of the array (x and y in the example) and one integer column to indicate the value.

All possible combinations of x and y are accounted for in the data, though it would be nice if a possible solution could substitute NULL for missing combinations of x and y.

The table looks as such:

DROP TABLE IF EXISTS t1;

CREATE TABLE t1 (
    x VARCHAR,
    y VARCHAR,
    val INT
);

INSERT INTO t1 (x, y, val)
VALUES   ('A', 'A', 1),
         ('A', 'B', 2),
         ('A', 'C', 3),
         ('B', 'A', 4),
         ('B', 'B', 5),
         ('B', 'C', 6),
         ('C', 'A', 7),
         ('C', 'B', 8),
         ('C', 'C', 9);

SELECT * FROM t1

How can I write this query to return a two-dimensional array?

Eg. the result of this specific query should be the following array:

SELECT '{{1,2,3},{4,5,6},{7,8,9}}'::integer[][]

回答1:


This is one way :

select array_agg(dimension1 order by x) as dimension2
from (
  select b.x, array_agg(t1.val order by a.y) as dimension1
  from 
    (select y from t1 group by y) a
  full join (select x from t1 group by x) b on true
  left join t1 on a.y = t1.y and b.x = t1.x
  group by b.x
) a;

This is similar and modern one :

with 
  a as (select y from t1 group by y),
  b as (select x from t1 group by x)
select array_agg(dimension1  order by x) as dimension2
from (
  select b.x, array_agg(t1.val order by a.y) as dimension1
  from a
  full join b on true
  left join t1 on a.y = t1.y and b.x = t1.x
  group by b.x
  order by b.x
) c;

to check if it gives null delete one row:

delete from t1 where x = 'A' and y = 'B';

and you should get :

{{1,NULL,3},{4,5,6},{7,8,9}}



回答2:


One possibility is to first group by x and use array_agg() to get the inner arrays. Then aggregate again using array_agg() to get the inner arrays into one outer array.

SELECT array_agg(a ORDER BY x)
       FROM (SELECT x,
                    array_agg(val ORDER BY y) a
                    FROM t1
                    GROUP BY x) t;


来源:https://stackoverflow.com/questions/55463151/postgres-table-to-two-dimensional-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!