Postgresql - 来自select的元素的Array_remove

时间:2018-04-03 09:03:52

标签: sql arrays postgresql

我有一个列(成员),其数组具有不同数量的元素。

e.g。

id   members (integer[])
1    {1, 3, 5, 7}
2    {4, 5, 7, 9}

我有一个表(unwanted_members),其中包含我想要删除的成员,例如

member
1
7

我想从数组中删除这些成员,即

id  members
1   {3, 5}
2   {4, 5, 9}

有人可以建议一个简单的方法吗?

2 个答案:

答案 0 :(得分:1)

@a_horse_with_no_name解决方案是完美的,如果扩展名intarray可用。如果没有,那么您可以使用表运算符执行某些操作UNIONINTERSECTEXCEPT

CREATE OR REPLACE FUNCTION array_remove(anyarray, anyarray)
RETURNS anyarray AS $$
SELECT ARRAY(SELECT unnest($1) EXCEPT SELECT unnest($2))
$$ LANGUAGE sql;

postgres=> select array_remove(ARRAY[1, 3, 5, 7],ARRAY[1,7]);
┌──────────────┐
│ array_remove │
╞══════════════╡
│ {3,5}        │
└──────────────┘
(1 row)

答案 1 :(得分:0)

如果您安装了intarray扩展程序,这很容易:

select id, members - (select array_agg(member) from unwanted_members)
from foo;

要更新表格,您可以使用:

update foo
    set members = members - (select array_agg(member) from unwanted_members);

如果没有该扩展,您首先需要取消成员ID删除不需要的内容,然后将它们聚合回数组:

select f.id, array_agg(t.mid order by t.idx) as members
from foo f, unnest(f.members) with ordinality as t(mid,idx)
where t.mid not in (select member from unwanted_members)
group by f.id;

要更新现有值,请使用:

update foo
  set members = x.members
from (
  select f.id, array_agg(t.mid order by t.idx) as members
  from foo f, unnest(f.members) with ordinality as t(mid,idx)
  where t.mid not in (select id from unwanted_members)
  group by f.id
) x
where foo.id = x.id;

假设id是表格的主键。