postgresql将数组聚合为具有所有元素的并集的单个数组

skm*_*hur 5 sql arrays postgresql aggregate-functions

我正在寻找用于聚集数组的聚集函数的sql模式。如果我有2行:

|id  |     array     |
|----+---------------|
|1   |    [1,2,3,4]  |
|1   |    [5,6]      |
|1   |    [7,8]      |
|--------------------|
Run Code Online (Sandbox Code Playgroud)

我要执行以下操作:

select id, *aggregate_function*(array) from table group by id

我希望结果是:

|id   | *aggregate_function*  |
|-----+-----------------------|
|1    | [1,2,3,4,5,6,7,8]     |
|-----------------------------|
Run Code Online (Sandbox Code Playgroud)

没有本机的postgres函数执行此聚合。但是也许这里可以使用sql模式?

Tre*_*reg 8

一种选择是创建自定义聚合:

CREATE FUNCTION array_union(a ANYARRAY, b ANYARRAY)
RETURNS ANYARRAY AS
$$
  SELECT array_agg(x)
  FROM (
    SELECT unnest(a) x
    UNION ALL
    SELECT unnest(b)
  ) AS u
$$ LANGUAGE SQL;

CREATE AGGREGATE array_union_agg(ANYARRAY) (
  SFUNC = array_union,
  STYPE = ANYARRAY,
  INITCOND = '{}'
);

Run Code Online (Sandbox Code Playgroud)

然后您可以简单地使用:

WITH x(arr) AS (
  VALUES
    (ARRAY[1,2,3,4]),
    (ARRAY[5,6]),
    (ARRAY[7,8])
)
SELECT array_union_agg(arr)
FROM x;
Run Code Online (Sandbox Code Playgroud)

查询结果为:

 array_union_agg
-----------------
 {1,2,3,4,5,6,7,8}
Run Code Online (Sandbox Code Playgroud)

上面的版本进行了数组串联

通过在函数定义中替换with可以实现真正的并集,就好像数组是集合一样。UNION ALLUNIONarray_union


Vin*_*ent 6

这样的事情应该起作用:

with mytable as
(
select 1 as id, array[1, 2, 3, 4] as myarray

union all

select 1 as id, array[5, 6] as myarray

union all 

select 1 as id, array[7, 8] as myarray
)

select
  id,
  array_agg(elements order by elements)
from mytable, unnest(myarray) as elements
group by id
Run Code Online (Sandbox Code Playgroud)

这里有一些关于构建自定义函数的讨论:在分组/聚合过程中串联/合并数组值


Hal*_*Ali 6

您可以取消嵌套,然后按以下方式分组:

WITH x (id, arr) AS (
  VALUES 
    (1, ARRAY[1,2,3,4])
  , (1, ARRAY[5,6])
  , (1, ARRAY[7, 8])
)
SELECT id, ARRAY_AGG(splitup) 
FROM (
    SELECT 
        id
      , unnest(arr) splitup 
    FROM x) splitup
GROUP BY 1
Run Code Online (Sandbox Code Playgroud)