Удалить одно неуникальное значение из массива - PullRequest
0 голосов
/ 05 марта 2019

С учетом этой таблицы в PostgreSQL 9.6:

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

Со строкой вроде:

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

Как мне удалить одно значение 'B'?

Я не могу использовать:

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

, поскольку он удаляет все элементы значения 'B'.Я просто пытаюсь удалить один элемент (скажем, первый).

Есть идеи?

Ответы [ 3 ]

0 голосов
/ 05 марта 2019

Я нашел ответ после расширения информации, представленной на этой странице (предложено Шароном Беном Ашером) https://dba.stackexchange.com/questions/94639/delete-array-element-by-index

, создав упомянутую здесь функцию:

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]';

и реализовав array_positionвдобавок ко всему, последнее утверждение для примера:

UPDATE test_table SET test_array = f_array_remove_elem(test_array, array_position(test_array, 'B')) WHERE id = 1;
0 голосов
/ 05 марта 2019

На основании моего старого ответа на dba.SE, который вы нашли и нашли хорошее применение:

Вы можете сделать еще один шаг вперед:

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';

Эта функция принимает значение удаляемого элемента в качестве второго параметра.Используя полиморфный псевдотип anyelement соответственно, чтобы сделать эту работу для любого типа массива.

Тогда UPDATE просто будет:

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

db <> fiddle здесь

При использовании моей исходной функции f_array_remove_elem(), которая занимает позицию индекса вместо значения элемента, вы можете обойтись без подзапроса:

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

Может быть даже немного быстрее, чем моя новая функция.
И обратите внимание, что более простая версия в нижней части моего старого ответа работает для Postgres 9.6.

0 голосов
/ 05 марта 2019

Вы можете попробовать с этим

select SUBSTRING ( '{A,A,A,B,B,B}',1,position('B' in '{A,A,A,B,B,B}') -1)||SUBSTRING ('{A,A,A,B,B,B}',position('B' in '{A,A,A,B,B,B}')+1)

Сначала найдите позицию B в строке, затем найдите подстроку до первого появления B, то есть '{A, A, A, затемполучить подстроку оставшейся строки, выходящей из B, т. е. B, B} '

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