postgresql 如果数组元素尚未包含,则添加它

acruukt9  于 2023-03-12  发布在  PostgreSQL
关注(0)|答案(2)|浏览(117)

我试图将整数添加到一个数组中,如果这个数组中还不存在整数的话。但是下面的代码会产生重复值:

User.update(
{
    'topics': sequelize.fn('array_append', sequelize.col('topics'), topicId),
},
{where: {uuid: id}})

PostgreSQL/sequelize中是否有与MongoDB $addToSet等效的函数?

yuvru6vn

yuvru6vn1#

引用MongoDB手册:
$addToSet运算符向数组中添加一个值,除非该值已经存在,在这种情况下,$addToSet不对该数组执行任何操作。
此SQL命令执行您所要求的操作:

UPDATE "user"
SET    topics = topics || topicId
WHERE  uuid = id
AND    NOT (topics @> ARRAY[topicId]);

@>是包含运算符的数组,在本例中是||数组到元素的连接。详细信息请参阅此处的手册。
相关:

  • 检查Postgres数组中是否存在值

不适用于null值。在这种情况下,请考虑:array_position(topics, topicId) IS NULL。请参见:

  • 检查Postgres数组中是否存在NULL

你可以把它 Package 成一个简单的函数:

CREATE OR REPLACE FUNCTION f_array_append_uniq (anyarray, anyelement)
  RETURNS anyarray
  LANGUAGE sql IMMUTABLE PARALLEL SAFE AS
 'SELECT CASE WHEN array_position($1,$2) IS NULL THEN $1 || $2 ELSE $1 END;'

像这样使用它:

...
SET    topics = f_array_append_uniq (topics, topicId)
...

但是顶部的查询甚至只在列值实际改变时才写入新的行版本。要实现相同的目的(不使用函数):

UPDATE "user"
SET    topics = topics || topicId
WHERE  uuid = id
AND    array_position(topics,topicId) IS NOT NULL;

最后一个是我最喜欢的。
参见:

  • 如何(或可以)对多列执行SELECT DISTINCT操作?
qyswt5oh

qyswt5oh2#

我也遇到过同样的问题,这就是我解决的方法。

const user = User.findOne({where: {id}})
User.update({topics: (user.topics.indexOf('topicId') > -1) ? user.topics : Sequelize.fn('array_append', Sequelize.col('topics'), topicId) }, {where: {id}})

不过,我觉得肯定有更好的办法。

相关问题