如何将所有记录中的所有整数数组合并到postgres中的单个数组中

时间:2014-03-27 03:03:47

标签: sql arrays postgresql

我有一个整数数组类型的列。如何将所有这些合并为一个整数数组?

例如:如果我执行查询:

select column_name from table_name

我得到的结果为:

-[RECORD 1]----------
column_name | {1,2,3}
-[RECORD 2]----------
column_name | {4,5}

如何将{1,2,3,4,5}作为最终结果?

4 个答案:

答案 0 :(得分:30)

您可以使用unnest打开数组,然后array_agg将它们重新组合在一起:

select array_agg(c)
from (
  select unnest(column_name)
  from table_name
) as dt(c);

答案 1 :(得分:11)

定义一个简单的自定义聚合:

CREATE AGGREGATE array_cat_agg(anyarray) (
  SFUNC=array_cat,
  STYPE=anyarray
);

并使用它:

WITH v(a) AS ( VALUES (ARRAY[1,2,3]), (ARRAY[4,5,6,7]))
SELECT array_cat_agg(a) FROM v;

如果您需要特定订单,请将其置于汇总调用中,即array_cat_agg(a ORDER BY ...)

对于n行,这大约是O(n log n)(我认为)。为了获得更好的性能,您需要在C中编写它,在这里您可以使用更高效(但可怕的)使用PostgreSQL数组的C API来避免每次迭代重新复制数组。

答案 2 :(得分:0)

你能做到这一点的唯一方法是在一个函数中:

CREATE FUNCTION merge_arrays() RETURNS int[] AS $$
DECLARE
  this record;
  res  int[];
BEGIN
  FOR this IN
    SELECT column_name FROM table_name
  LOOP
    array_cat(res, this.column_name);
  END LOOP;
  RETURN res;
END; $$ LANGUAGE plpgsql;

然后你可以

SELECT merge_arrays();

获得您正在寻找的结果。

这当然会将您的表定义硬编码到函数中,这可能(或可能不是)成为问题。此外,您可能希望在循环查询中放置WHERE子句以限制要追加其数组的记录;您可以使用其他函数参数来执行此操作。

请记住,当您的表格增加并且可能会影响性能时,您可能会得到一个非常大的数组。你真的需要一个大阵列中所有记录的所有子数组吗?查看您的应用程序,看看您是否可以在该级别进行合并,而不是在单个查询中进行。

答案 3 :(得分:0)

您可以使用lateral subquery

select array_agg(u.a)
from (values (array[1, 2, 3]), (array[4, 5])) t (a)
    join lateral unnest(t.a) u (a) on true;