Postgres – Функция возврата пересечения двух массивов?

В postgresql вы можете использовать оператор && для возврата t (true), если два массива имеют общие элементы, то есть они перекрываются. Есть ли функция / оператор, который вернет то, что эти общие члены?

т.е. что-то вроде этого

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

Начиная с 8.4, в Postgres есть полезные встроенные функции, которые упрощают и, возможно, быстрее выполняют функцию из первого ответа (вот что говорит мне EXPLAIN: «(cost = 0.00..0.07 rows = 1 width = 64)» для этого запроса vs . "(cost = 0.00..60.02 rows = 1 width = 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'])); 

Попробовать & вместо &&

Подробнее см. В документах PostgreSQL .

 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 

Работает и с нецелыми массивами.

Вы можете использовать эту функцию:

 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[]); 

один другой способ ..

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

Если вы не возражаете при установке расширения, расширение intarray предоставляет оператору & для этого, как указано @dwc:

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

Возвращает {2} .