【问题标题】:Remove one, non-unique value from an array从数组中删除一个非唯一值
【发布时间】:2019-03-04 22:01:06
【问题描述】:

鉴于 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”的所有个元素。我只是想删除一个元素(比如第一个元素)。

有什么想法吗?

【问题讨论】:

  • 看到这个问题来自 DBA SE dba.stackexchange.com/questions/94639/…
  • 这是假设我知道字符串的确切索引。我需要一个可以输入字符串的函数,它会找到包含该字符串的第一个索引,然后从数组中删除该索引。
  • 您只需将“位置('B'”中的“B”替换为您要替换的字符/字符串。就像您在示例函数中传递“B”)array_remove(test_array , 'B')

标签: sql arrays postgresql sql-update


【解决方案1】:

根据我在 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小提琴here

虽然使用我的原始函数 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。

【讨论】:

    【解决方案2】:

    我在扩展此页面上提供的信息后找到了答案(由 Sharon Ben Asher 建议) 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;
    

    【讨论】:

    • 旁白:为什么演员test_array::text[]。列已经是text[],不是吗?
    • 删除了不必要的子查询和强制转换,感谢您的帮助
    • 我买了一只流浪SELECT
    【解决方案3】:

    你可以试试这个

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

    【讨论】:

      猜你喜欢
      • 2018-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-19
      • 2016-12-19
      相关资源
      最近更新 更多