加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

PostgreSQL中多个数组的交集

发布时间:2020-12-13 16:32:40 所属栏目:百科 来源:网络整理
导读:我有一个定义为: 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'; 这是
我有一个定义为:
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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读