postgresql Postgres -返回两个数组的交集的函数?

sg2wtvxw  于 2022-11-04  发布在  PostgreSQL
关注(0)|答案(8)|浏览(714)

在postgresql中,如果两个数组有共同的成员,也就是说它们重叠,你可以使用&&运算符来返回t(true)。有没有函数/运算符可以返回那些共同的成员是什么?
比如说

select arrray_intersection(ARRAY[1, 4, 2], ARRAY[2, 3]);
ARRAY[2]
vohkndzv

vohkndzv1#

Since 8.4, there are useful builtins in Postgres,这使得从第一个答案开始的函数更容易,也可能更快(无论如何,这就是EXPLAIN告诉我的:此查询的“(成本= 0.00..07行=1宽度=64)”与原始查询的“(成本=0.00..60.02行=1宽度=64)”)。
简化代码为:

SELECT ARRAY
    (
        SELECT UNNEST(a1)
        INTERSECT
        SELECT UNNEST(a2)
    )
FROM  (
        SELECT  array['two', 'four', 'six'] AS a1
              , array['four', 'six', 'eight'] AS a2
      ) q;

你可以把它变成一个函数

CREATE FUNCTION array_intersect(anyarray, anyarray)
  RETURNS anyarray
  language sql
as $FUNCTION$
    SELECT ARRAY(
        SELECT UNNEST($1)
        INTERSECT
        SELECT UNNEST($2)
    );
$FUNCTION$;

你可以称之为

SELECT array_intersect(array['two', 'four', 'six']
                     , array['four', 'six', 'eight']);

但您也可以将其称为内联:

SELECT array(select unnest(array['two', 'four', 'six']) intersect
              select unnest(array['four', 'six', 'eight']));
j8ag8udp

j8ag8udp2#

尝试&而不是&&
请参阅PostgreSQL Docs了解更多信息。

1cosmwyk

1cosmwyk3#

只是另一种方法..

SELECT ARRAY( SELECT * FROM UNNEST( $1 ) WHERE UNNEST = ANY( $2 ) );
w9apscun

w9apscun4#

如果你不介意安装一个扩展,intarray extension提供了&操作符来完成这个操作,正如@dwc所指出的那样:

SELECT ARRAY[1, 4, 2] & ARRAY[2, 3];

返回{2}

9rbhqvlz

9rbhqvlz5#

您可以使用此函数:

CREATE OR REPLACE FUNCTION intersection(anyarray, anyarray) RETURNS anyarray as $$
SELECT ARRAY(
    SELECT $1[i]
    FROM generate_series( array_lower($1, 1), array_upper($1, 1) ) i
    WHERE ARRAY[$1[i]] && $2
);
$$ language sql;

它可以与任何类型的数组一起使用,您可以像这样使用它:

SELECT intersection('{4,2,6}'::INT4[], '{2,3,4}'::INT4[]);
rfbsl7qr

rfbsl7qr6#

SELECT  ARRAY
        (
        SELECT  a1[s]
        FROM    generate_series(array_lower(a1, 1), array_upper(a1, 1)) s
        INTERSECT
        SELECT  a2[s]
        FROM    generate_series(array_lower(a2, 1), array_upper(a2, 1)) s
        )
FROM    (
        SELECT  array['two', 'four', 'six'] AS a1, array['four', 'six', 'eight'] AS a2
        ) q

也适用于非整数数组。

n3ipq98p

n3ipq98p7#

对于使用postgresql的用户来说,另一个选择是利用jsonb_path_exists工具来检查一个数组中是否至少有一个元素在另一个数组中也可用!
例如,假设下面我们有一个表activity_role,它包含JSONB格式的列“rights”,在其中我们可以找到例如
表:活动角色
| 标识符|权限|
| - -|- -|
| 一个|{“文件夹”:[“写入”,“读取”,“分配”]}|
例如,如果我们要检查id 1是否至少具有以下权限之一['sign',approve ',' write '],则只需运行

SELECT jsonb_path_exists(ar.rights, '$.folders[*] ? (@ == $requested_right)',jsonb_build_object('requested_right', array['sign', 'approve', 'write']) AS authorized FROM activity_rights ar WHERE ar.id = 1;

结果将是
授权的
真的
因为至少'write'在数组1(权限-〉'文件夹')和数组2(数组['sign',approve ',' write '])中匹配

e3bfsja2

e3bfsja28#

内联操作&&SELECT语句中的外观,在该语句中,我们从2个表中进行选择,并仅在两个数组列相交的地方进行筛选(至少1个值)

SELECT
    table_1 .list::text[],
    table_2 .list::text[]
FROM
    table_1,
    table_2
WHERE
    table_1.list::text[] && table_2.list::text[]

相关问题