Postgres - функция для возврата пересечения 2 массивов? - PullRequest
24 голосов
/ 16 апреля 2009

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

т.е. как то так

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

Ответы [ 6 ]

49 голосов
/ 29 апреля 2011

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

Попробуйте & вместо &&

Подробнее см. Документы PostgreSQL .

4 голосов
/ 24 мая 2016

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

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

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

4 голосов
/ 11 октября 2012

один другой метод ..

SELECT ARRAY( SELECT * FROM UNNEST( $1 ) WHERE UNNEST = ANY( $2 ) );
4 голосов
/ 17 апреля 2009

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

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[]);
4 голосов
/ 16 апреля 2009
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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...