sql - 使用聚合函数更新 json 数组

标签 sql json postgresql python-2.7 psycopg2

使用 Postgres 9.3、Python 2.7、psycopg2。
我有一个名为 SomeTable 的表,其中包含一个 json 字段 some_json_arrayrow_id 键。

some_json_array 看起来像这样:

"[{'key': 'value_one'}, {'key': 'value_two'}, etc]"

我还有一个函数,其中我试图将一些元素添加到与给定的 row_id 相对应的 SomeTable 的 json 数组中。

我的代码如下:

CREATE OR REPLACE FUNCTION add_elements (insertion_id smallint, new_elements_json json)
RETURNS void AS $$
BEGIN
    UPDATE SomeTable
    SET some_json_array = (SELECT array_to_json(array_agg(some_json_array) || array_agg(new_elements_json)))
    WHERE row_id = insertion_id;
END;
$$ LANGUAGE plpgsql;

我收到以下错误:

Cannot use aggregate function in UPDATE

我认为这是在提示 array_agg()

我应该如何修改这个函数以使其工作?如有必要,我可以将 WHERE 子句粘贴到 SELECT 语句中。

最佳答案

聚合函数不能像普通函数一样使用,只能在聚合上下文中使用。

由于 Postgres 不能直接操作 JSON 数组(它只是一个有效的 json value 到 Postgres,而不是一个数组)你必须......

  • 要么将 json 值转换为 text,连接新元素,生成有效的 JSON 语法并转换回来,
  • 或转换为 json 的 Postgres 数组:json[],附加新元素并将此 Postgres 数组转换回 json值(value)。
    array_to_json() 足够聪明,不会再对 Postgres 数组的 json 元素进行编码。

第一种方法更容易出错。您将不得不手动构建有效的 JSON。这是第二个变体的实现:

CREATE OR REPLACE FUNCTION add_elements (_id int2, _elem json)
  RETURNS void AS
$func$
BEGIN
    UPDATE SomeTable s
    SET    some_json_array = array_to_json(ARRAY(
              SELECT * FROM json_array_elements(s.some_json_array)
              UNION  ALL SELECT _elem
              ))
    WHERE  s.row_id = _id;
END
$func$ LANGUAGE plpgsql;

函数包装器大部分与问题无关。可以只是一个普通的 SQL 语句。

相关:

关于sql - 使用聚合函数更新 json 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28621738/

相关文章:

创建表中的 MySQL 日期格式

sql - 如何添加仅具有一组值选择的列?

java - 如何创建接收 Gson().fromJson() 的对象

php - responseLitsner 中缺少字段 - Android Studio

mysql - SQL 计数等于 1 个值的记录,并对其余的进行计数和分组

java - 在 MySQL 数据库上使用 HQL 使用子查询(联接到同一个表)进行更新时出现问题。

Android/Retrofit HAL JSON 支持

postgresql - 有没有一种简单的方法可以消除 tsvector 中词素的出现?

sql - 尝试对项目进行排名时出现 row_number 错误

postgresql - Ubuntu `env: ‘pg_dump’ : No such file or directory` error