Postgres表到二维数组

时间:2019-04-01 20:32:37

标签: arrays postgresql

我想将具有三列的表转换为integer[][]类型的二维数组。有两列表示数组的两个维中的每个维(在示例中为xy),一个integer列表示值。

在数据中考虑了x和y的所有可能组合,但是如果可能的解决方案可以用NULL替代xy的缺失组合会很好。 / p>

该表如下所示:

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

如何编写此查询以返回二维数组?

例如。此特定查询的结果应为以下数组:

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

2 个答案:

答案 0 :(得分:2)

一种可能性是首先对x进行分组,然后使用array_agg()来获取内部数组。然后再次使用array_agg()进行聚合,以将内部数组合并为一个外部数组。

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

答案 1 :(得分:2)

这是一种方式:

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;

这与现代类似:

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;

检查是否给null删除一行:

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

您应该得到:

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