我有一个类型为整数数组的列。如何将它们全部合并成一个单一的整数数组?
例如:如果我执行查询:
select column_name from table_name
我得到的结果集如下:
-[RECORD 1]----------
column_name | {1,2,3}
-[RECORD 2]----------
column_name | {4,5}
如何将{1,2,3,4,5}
作为最终结果?
我有一个类型为整数数组的列。如何将它们全部合并成一个单一的整数数组?
例如:如果我执行查询:
select column_name from table_name
我得到的结果集如下:
-[RECORD 1]----------
column_name | {1,2,3}
-[RECORD 2]----------
column_name | {4,5}
如何将{1,2,3,4,5}
作为最终结果?
定义一个简单的自定义聚合:
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 ...)
。O(n²)
,所以它不适用于长行集。为了获得更好的性能,您需要用C语言编写它,在那里您可以使用更有效率(但难以使用)的PostgreSQL数组的C API,以避免每次迭代重新复制数组。O(n^2)
内运行,因此不适用于大型数据集。来源:我在生产中使用它处理了一些大型数据集,但最终不得不将其删除 =) - John BledsoeO(n^2)
,你确定吗?每次迭代它都会复制整个数组,包括所有之前的成员,当它构建一个新的数组时。无论如何,对于长输入来说,它仍然会非常慢。 - Craig RingerO(n^2)
。 - John Bledsoenumpy
或intarray
的Python)或使用C来更有效地执行它。 - Craig Ringerstring_to_array(string_agg(array_to_string(column_name ,','),','),',')
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;
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
子句,以限制要添加其数组的记录;您可以使用另一个函数参数来实现这一点。
请记住,随着表大小的增加,您可能会得到一个非常大的数组,这可能会影响性能。您真的需要在一个大数组中获取所有记录的子数组吗?查看您的应用程序,看看是否可以在该级别上执行合并,而不是单个查询中执行合并。
with ordinality
来实现。 - Craig RingerWITH ORDINALITY
的详细信息。 - Erwin Brandstetter