2009-04-16 19 views
18

En postgresql, puede usar el operador & & para devolver t (verdadero) si dos matrices tienen miembros comunes, es decir, se superponen. ¿Hay una función/operador que devolverá lo que son esos miembros comunes?Postgres - Función para devolver la intersección de 2 ARRAY?

algo como esto decir

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

Respuesta

14

Trate & en lugar de &&

Ver PostgreSQL Docs por más.

+3

Probado, no funciona en stock, necesita una extensión instalada para que funcione. pero +1 de todos modos. –

+1

http://www.postgresql.org/docs/current/static/contrib.html # Necesito leer los datos aquí –

+0

Buena captura, Kent – dwc

4
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 

Funciona también en arreglos no enteros.

3

Se puede utilizar esta función:

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; 

que debería funcionar con cualquier tipo de matriz, y se puede utilizar de esta manera:

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

Since 8.4, there are useful builtins in Postgres que hacen the function from the first answer más fácil y posiblemente más rápido (eso es lo que EXPLAIN me dice, de todos modos: "(costo = 0.00..0.07 filas = 1 ancho = 64)" para esta consulta vs. "(costo = 0.00..60.02 filas = 1 ancho = 64)" para el original) .

El código simplificado es:

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

y sí, puede convertirlo en una función:

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

que se puede llamar como

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

pero puedes también llámelo en línea:

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

otro método en ..

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

Si no te importa la instalación de una prórroga, el intarray extension proporciona al operador & hacer esto como @dwc señaló .:

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

devoluciones {2}.

+0

¿Qué versión de postgresql estás usando? Con 9.6 obtengo el siguiente error y tampoco puedo encontrarlo en los documentos. ¿O estoy haciendo algo mal aquí? '' 'ERROR: el operador no existe: entero [] & entero [] LÍNEA 1: SELECCIONAR ARRAY [1,4,2] & ARRAY [2,3] ^ CONSEJO: Ningún operador coincide con el nombre de pila y tipos de argumento (s). Es posible que deba agregar moldes de tipo explícito .''' –

+2

Ah, espere, según https: //www.postgresql.org/docs/current/static/intarray.html, es una extensión de postgresql. Vale la pena mencionar eso. –

Cuestiones relacionadas