2015-12-15 4 views
0

У меня есть два массива в PostgreSQL:Учитывая два массива, как получить предметы, которые не в обоих?

CREATE OR REPLACE FUNCTION func() 
    RETURNS void AS 
$BODY$ 
declare 
     first integer[]; 
     second integer[]; 
     array_vb integer[]; 
     array_vb2 integer[]; 
begin 

    code.... 

    select array_agg(id) into first 
    from a 
    where id = any (array_vb); 

    select array_agg(id) into second 
    from a 
    where id = any (array_vb2); 

end; 
$BODY$ 
    LANGUAGE plpgsql VOLATILE 

Я хотел бы добавить raise notice, который будет печатать все элементы, которые в первый, но не во втором

, например:

first = [1,10,15,3,7] 

second = [1,3,15,4] 

он будет печатать 10,7

Как это сделать?

ответ

2

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

SELECT ARRAY(SELECT unnest(first) EXCEPT SELECT unnest(second)) 

Пример:

SELECT ARRAY(SELECT unnest(ARRAY[1,10,15,3,7]) EXCEPT SELECT unnest(array[1,3,15,4])) 

Дает:

array 
-------- 
{10,7} 

См. SQLFiddle here.

1

Вы можете использовать intarray extension:

create extension if not exists intarray; 

select array[1,10,15,3,7] - array[1,3,15,4] as result; 

result 
-------- 
{7,10} 
(1 row) 
0
create or replace function f(a1 int[], a2 int[]) 
returns void as $body$ 
begin 

    raise notice '%', (
     select string_agg(i::text, ',') 
     from 
      unnest (a1) a1(i) 
      left join 
      unnest (a2) a2(i) using (i) 
     where a2.i is null 
    ); 

end; 
$body$ language plpgsql volatile 
; 
select f(array [1,10,15,3,7], array [1,3,15,4]); 
NOTICE: 10,7 
f 
--- 

(1 row) 

Обратите внимание, что данная функция, как это, может быть помечена immutable

0

Вы можете создать функцию, которая возвращает желаемый результат массива:

create or replace function array_except(a1 int[], a2 int[]) 
    returns int[] 
as 
$$ 
    select array_agg(i) 
    from ( 
     select i 
     from unnest(a1) i 
     except 
     select a2 
     from unnest(a2) a2 
    ) t; 
$$ 
language sql; 

Функция возвращает массив, содержащий элементы, которые находятся в первом, но не во втором массиве.

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

create or replace function foo() 
    returns void 
as 
$BODY$ 
declare 
    _first integer[]; 
    _second integer[]; 
begin 

    _first := array[1,10,15,3,7]; 
    _second := array[1,3,15,4]; 
    raise notice 'Result %', array_except(_first, _second); 

end; 
$BODY$ 
LANGUAGE plpgsql; 
Смежные вопросы