Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove one, non-unique value from an array

Given this table in PostgreSQL 9.6:

CREATE TABLE test_table (
   id int PRIMARY KEY
 , test_array text[]
);

With a row like:

INSERT INTO test_table (id, test_array)
VALUES (1 , '{A,A,A,B,B,B}');

How would I remove one single 'B' value?

I cannot use:

UPDATE test_table
SET test_array = array_remove(test_array, 'B')
WHERE id = 1;

as it removes all elements of value 'B'. I am just looking to remove a single element (say, the first one).

Any ideas?

like image 871
R. StackUser Avatar asked Nov 30 '25 02:11

R. StackUser


2 Answers

Based on my old answer on dba.SE that you found and put to good use:

  • Delete array element by index

You might take it one step further:

CREATE OR REPLACE FUNCTION f_array_remove_elem1(anyarray, anyelement)
  RETURNS anyarray LANGUAGE sql IMMUTABLE AS
'SELECT $1[:idx-1] || $1[idx+1:] FROM array_position($1, $2) idx';

This function takes the value of the element to remove as 2nd parameter. Using the polymorphic pseudo-type anyelement accordingly to make this work for any array type.

Then the UPDATE simply is:

UPDATE test_table
SET    test_array = f_array_remove_elem1(test_array, 'B')
WHERE  id = 1;

db<>fiddle here

While using my original function f_array_remove_elem() that takes the index position instead of the element value, you could do without a subquery:

UPDATE test_table
SET    test_array = f_array_remove_elem(test_array, array_position(test_array, 'B'))
WHERE  id = 1;

Might even be a bit faster than my new function.
And note that the simpler version at the bottom of my old answer works for Postgres 9.6.

like image 156
Erwin Brandstetter Avatar answered Dec 02 '25 18:12

Erwin Brandstetter


I found the answer after expanding on the information provided on this page (suggested by Sharon Ben Asher) https://dba.stackexchange.com/questions/94639/delete-array-element-by-index

creating the function mentioned there:

CREATE OR REPLACE FUNCTION f_array_remove_elem(anyarray, int)
RETURNS anyarray LANGUAGE sql IMMUTABLE AS
'SELECT $1[1:$2-1] || $1[$2+1:2147483647]';

and implementing array_position on top of this, the final statement for the example:

UPDATE test_table SET test_array = f_array_remove_elem(test_array, array_position(test_array, 'B')) WHERE id = 1;
like image 32
R. StackUser Avatar answered Dec 02 '25 18:12

R. StackUser



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!