Reputation: 399
Is it possible to remove multiple elements from an array? Before removing elements Array1 is :
{1,2,3,4}
Array2 that contains some elements I wish to remove:
{1,4}
And I want to get:
{2,3}
How to operate?
Upvotes: 26
Views: 50133
Reputation: 494
You can use this function for when you are dealing with bigint/int8 numbers and want to maintain order:
CREATE OR REPLACE FUNCTION arr_subtract(int8[], int8[])
RETURNS int8[] AS
$func$
SELECT ARRAY(
SELECT a
FROM unnest($1) WITH ORDINALITY x(a, ord)
WHERE a <> ALL ($2)
ORDER BY ord
);
$func$ LANGUAGE sql IMMUTABLE;
I got this solution from the following answer to a similar question: https://stackoverflow.com/a/8584080/1544473
Upvotes: 2
Reputation: 163
User array re-dimension annotation
array[<start index>:<end index>]
WITH t(stack, dim) as (
VALUES(ARRAY[1,2,3,4], ARRAY[1,4])
) SELECT stack[dim[1]+1:dim[2]-1] FROM t
Upvotes: 0
Reputation: 3471
This answer is the simplest I think: https://stackoverflow.com/a/6535089/673187
SELECT array(SELECT unnest(:array1) EXCEPT SELECT unnest(:array2));
so you can easily use it in an UPDATE
command, when you need to remove some elements from an array column:
UPDATE table1 SET array1_column=(SELECT array(SELECT unnest(array1_column) EXCEPT SELECT unnest('{2, 3}'::int[])));
Upvotes: 9
Reputation: 121574
Use unnest()
with array_agg()
, e.g.:
with cte(array1, array2) as (
values (array[1,2,3,4], array[1,4])
)
select array_agg(elem)
from cte, unnest(array1) elem
where elem <> all(array2);
array_agg
-----------
{2,3}
(1 row)
If you often need this functionality, define the simple function:
create or replace function array_diff(array1 anyarray, array2 anyarray)
returns anyarray language sql immutable as $$
select coalesce(array_agg(elem), '{}')
from unnest(array1) elem
where elem <> all(array2)
$$;
You can use the function for any array, not only int[]
:
select array_diff(array['a','b','c','d'], array['a','d']);
array_diff
------------
{b,c}
(1 row)
Upvotes: 23
Reputation: 737
With some help from this post:
select array_agg(elements) from
(select unnest('{1,2,3,4}'::int[])
except
select unnest('{1,4}'::int[])) t (elements)
Result:
{2,3}
Upvotes: 18
Reputation: 382122
With the intarray extension, you can simply use -
:
select '{1,2,3,4}'::int[] - '{1,4}'::int[]
Result:
{2,3}
You'll need to install the intarray extension if you didn't already. It adds many convenient functions and operators if you're dealing with arrays of integers.
Upvotes: 12