Удалить значения массива в pgSQL - PullRequest
29 голосов
/ 15 января 2010

Есть ли способ удалить значение из массива в pgSQL? Или, чтобы быть более точным, чтобы вытолкнуть последнее значение? Судя по этому списку ответ вроде бы нет. Я могу получить желаемый результат с помощью дополнительного указателя индекса, но это немного громоздко.

Ответы [ 10 ]

77 голосов
/ 07 декабря 2014

В версии 9.3 и выше вы можете сделать:

update users set flags = array_remove(flags, 'active')
19 голосов
/ 01 февраля 2013

Самый простой способ удалить последнее значение:

array1 = array[1,2,3]
array1 = ( select array1[1:array_upper(array1, 1) - 1] )
10 голосов
/ 15 января 2010

Нет, я не думаю, что вы можете. По крайней мере, без написания чего-то ужасного, вроде:

SELECT ARRAY (
 SELECT UNNEST(yourarray) LIMIT (
  SELECT array_upper(yourarray, 1) - 1
 )
)
9 голосов
/ 26 марта 2013

Существует простой способ удалить значение из массива в PLAIN SQL:

SELECT unnest('{5,NULL,6}'::INT[]) EXCEPT SELECT NULL

удалит все значения NULL из массива. Результат будет:

#| integer |
------------
1|    5    |
2|    6    |
9 голосов
/ 15 января 2010

Я не уверен в вашем контексте, но это должно дать вам кое-что для работы:

CREATE TABLE test (x INT[]);
INSERT INTO test VALUES ('{1,2,3,4,5}');

SELECT x AS array_pre_pop,
       x[array_lower(x,1) : array_upper(x,1)-1] AS array_post_pop, 
       x[array_upper(x,1)] AS popped_value 
FROM test;


 array_pre_pop | array_post_pop | popped_value 
---------------+----------------+--------------
 {1,2,3,4,5}   | {1,2,3,4}      |            5
5 голосов
/ 23 января 2013

Вот функция, которую я использую для целочисленных [] массивов

CREATE OR REPLACE FUNCTION array_remove_item (array_in INTEGER[], item INTEGER)
RETURNS INTEGER[]
LANGUAGE SQL
AS $$
SELECT ARRAY(
  SELECT DISTINCT $1[s.i] AS "foo"
    FROM GENERATE_SERIES(ARRAY_LOWER($1,1), ARRAY_UPPER($1,1)) AS s(i)
   WHERE $2 != $1[s.i]
   ORDER BY foo
);
$$;

Это очевидно для целочисленных массивов, но может быть изменено для ANYARRAY ANYELEMENT

=> select array_remove_item(array[1,2,3,4,5], 3);
-[ RECORD 1 ]-----+----------
array_remove_item | {1,2,4,5}
3 голосов
/ 04 июня 2013

Я работаю на 9.2 и могу выполнить это:

update tablename set arrcolumn=arrcolumn[1:array_length(arrcolumn)-1];

или вы можете сдвинуть передний элемент с помощью такой же вещи:

update tablename set arrcolumn=arrcolumn[2:array_length(arrcolumn)];

Осторожно, программисты - по какой-то причине, до сих пор неизвестной науке, массивы pgsql индексируются 1, а не 0.

2 голосов
/ 25 ноября 2011

Я создал функцию array_pop, чтобы вы могли удалить элемент с известным значением из массива.

CREATE OR REPLACE FUNCTION array_pop(a anyarray, element character varying)
RETURNS anyarray
LANGUAGE plpgsql
AS $function$
DECLARE 
    result a%TYPE;
BEGIN
SELECT ARRAY(
    SELECT b.e FROM (SELECT unnest(a)) AS b(e) WHERE b.e <> element) INTO result;
RETURN result;
END;
$function$ 

есть также гист версия https://gist.github.com/1392734

1 голос
/ 09 сентября 2013

Попробуйте это:

update table_name set column_name=column_name[1:array_upper(column_name, 1)-1];
0 голосов
/ 25 октября 2013

Моя функция для всех типов массивов.

Внешняя функция:

CREATE OR REPLACE FUNCTION "outer_array"(anyarray, anyarray) RETURNS anyarray AS $$
    SELECT
        "new"."item"
    FROM (
        SELECT
            ARRAY(
                SELECT
                    "arr"."value"
                FROM (
                    SELECT
                        generate_series(1, array_length($1, 1)) AS "i",
                        unnest($1)                              AS "value"
                ) "arr"
                WHERE
                    "arr"."value" <> ALL ($2)
                ORDER BY
                    "arr"."i"
            ) AS "item"
    ) "new"
    $$
LANGUAGE sql
IMMUTABLE
RETURNS NULL ON NULL INPUT
;

Внутренняя функция:

CREATE OR REPLACE FUNCTION "inner_array"(anyarray, anyarray) RETURNS anyarray AS $$
    SELECT
        "new"."item"
    FROM (
        SELECT
            ARRAY(
                SELECT
                    "arr"."value"
                FROM (
                    SELECT
                        generate_series(1, array_length($1, 1)) AS "i",
                        unnest($1)                              AS "value"
                ) "arr"
                WHERE
                    "arr"."value" = ANY ($2)
                ORDER BY
                    "arr"."i"
            ) AS "item"
    ) "new"
$$
LANGUAGE sql
IMMUTABLE
RETURNS NULL ON NULL INPUT
;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...