PostgreSQL中多个数组的交集

我有一个定义为:
CREATE VIEW View1 AS 
 SELECT Field1,Field2,array_agg(Field3) AS AggField 
 FROM Table1 
 GROUP BY Field1,Field2;

我想做的是让AggField中的数组与以下类似:

SELECT intersection(AggField) FROM View1 WHERE Field2 = 'SomeValue';

这是否可能,还是有更好的方式来实现我想要的?

我可以想到的与阵列交点最近的事情是这样的:
select array_agg(e)
from (
    select unnest(a1)
    intersect
    select unnest(a2)
) as dt(e)

这假设a1和a2是具有相同类型元素的单维数组.你可以把它放在一个这样的函数中:

create function array_intersect(a1 int[],a2 int[]) returns int[] as $$
declare
    ret int[];
begin
    -- The reason for the kludgy NULL handling comes later.
    if a1 is null then
        return a2;
    elseif a2 is null then
        return a1;
    end if;
    select array_agg(e) into ret
    from (
        select unnest(a1)
        intersect
        select unnest(a2)
    ) as dt(e);
    return ret;
end;
$$language plpgsql;

那么你可以这样做:

=> select array_intersect(ARRAY[2,4,6,8,10],ARRAY[1,2,3,5,7,9,10]);
 array_intersect 
-----------------
 {6,10,8}
(1 row)

请注意,这不保证返回的数组中的任何特定顺序,但如果您关心它,您可以修复它.那么你可以创建自己的聚合函数

-- Pre-9.1
create aggregate array_intersect_agg(
    sfunc    = array_intersect,basetype = int[],stype    = int[],initcond = NULL
);

-- 9.1+ (AFAIK,I don't have 9.1 handy at the moment
-- see the comments below.
create aggregate array_intersect_agg(int[]) (
    sfunc = array_intersect,stype = int[]
);

现在我们看到为什么array_intersect有趣,有些是有空的NULL.我们需要一个初始值,这个聚合行为像通用集,我们可以使用NULL(是的,这闻起来有点儿,但我不能想到任何比我头顶更好的东西).

一旦这一切都到位,你可以这样做:

> select * from stuff;
    a    
---------
 {1,3}
 {1,3}
 {3,5}
(3 rows)

> select array_intersect_agg(a) from stuff;
 array_intersect_agg 
---------------------
 {3}
(1 row)

不完全简单或高效,但可能是一个合理的起点,而不是完全没有.

实用参考文献

> array_agg
> create aggregate
> create function
> PL/pgSQL
> unnest

相关文章

项目需要,有个数据需要导入,拿到手一开始以为是mysql,结果...
本文小编为大家详细介绍“怎么查看PostgreSQL数据库中所有表...
错误现象问题原因这是在远程连接时pg_hba.conf文件没有配置正...
因本地资源有限,在公共测试环境搭建了PGsql环境,从数据库本...
wamp 环境 这个提示就是说你的版本低于10了。 先打印ph...
psycopg2.OperationalError: SSL SYSCALL error: EOF detect...