如何将两个 PostgreSQL 列聚合到一个用括号分隔的数组中

Posted

技术标签:

【中文标题】如何将两个 PostgreSQL 列聚合到一个用括号分隔的数组中【英文标题】:How to aggregate two PostgreSQL columns to an array separated by brackets 【发布时间】:2017-01-05 20:57:31 【问题描述】:

我想使用 group-by 查询连接两列,从而生成一个用括号分隔的数组。我知道这个问题与this 问题有关,但和往常一样,我的用例有点不同。

一个简单的例子(也称为SQL Fiddle)。 目前我的查询返回以下内容:

ID  X   Y
3   0.5 2.71
3   1.0 2.50
3   1.5 2.33
6   0.5 2.73
6   1.5 2.77

但我想连接/聚合X/Y 列以获得以下内容:

ID  XY
3   [[0.5,2.71],[1.0,2.50],[1.5,2.33]]
6   [[0.5,2.73],[1.5,2.77]]

目前我尝试将列连接为一个,如下所示:

SELECT "ID",concat_ws(', ',"X", "Y") as XY FROM Table1;

返回:

ID  xy
3   0.5, 2.71
3   1, 2.50
3   1.5, 2.33
6   0.5, 2.73

并使用array_agg()

SELECT "ID",array_to_string(array_agg("X"),',') AS XY
FROM Table1
GROUP BY "ID";

导致:

ID  xy
3   0.5,1,1.5
6   0.5

我觉得我越来越近了,但如果能伸出援助之手,我们将不胜感激。

【问题讨论】:

【参考方案1】:

从两列创建一个数组,聚合该数组:

select id, array_agg(array[x,y])
from the_table
group by id;

请注意,数组的默认文本表示使用大括号 (..) 而不是方括号 ([..])

【讨论】:

感谢您的快速响应,它在 postgresql 中完美运行(不在 sqlfiddle 中) @Mattijn:您的版本显然是 9.5 或更高版本。 sqlfiddle 卡在 9.3 已经有一段时间了。 另外,x 和 y 的类型应该相同,即如果 x 是文本,那么 y 也应该是文本类型。如果没有,需要使用大小写。(::text)【参考方案2】:

在 Postgres 9.5 或更高版本中,array_agg()arrays 作为输入以允许使用简单语法 provided by @a_horse:

SELECT id, array_agg(ARRAY[x, y]) AS xy
FROM   Table1
GROUP  BY id;

旧版本中,这还没有实现。您可以创建自己的聚合函数(一次)来实现相同的目的:

CREATE AGGREGATE array_agg_mult (anyarray)  (
    SFUNC     = array_cat
  , STYPE     = anyarray
  , INITCOND  = ''
);

然后:

SELECT id, array_agg_mult(ARRAY[ARRAY[x,y]]) AS xy  -- note the 2D array
FROM   Table1
GROUP  BY id;

详情:

Selecting data into a Postgres array

或者你可以连接一个字符串:

SELECT id, '[[' || string_agg(concat_ws(',', x, y), '],[') || ']]' AS xy
FROM   Table1
GROUP  BY id;

准确地产生您想要的结果。一个字符串,而不是一个数组。

【讨论】:

以上是关于如何将两个 PostgreSQL 列聚合到一个用括号分隔的数组中的主要内容,如果未能解决你的问题,请参考以下文章

如何在 PostgreSQL 中按时间间隔聚合行数?

如何使用 postgresql 按多列中表示的值进行聚合

postgreSQL 选择聚合函数中未使用的附加列

如何在一个 groupby 列上执行聚合选项,给出两列输出

PostgreSQL 9.6 在对时间戳列进行聚合期间选择了错误的计划

Django 与 Postgresql,列必须出现在 GROUP BY 子句中或在聚合函数中使用