Postgres:使用给定的键集和默认值创建jsonb对象

时间:2018-12-12 09:13:25

标签: json postgresql jsonb postgresql-9.6

我正在使用PostgreSQL 9.6。我有一个像ARRAY['a', 'b']::text[]这样的数组,它来自应用程序代码,并在SQL中进行了转换,所以我不知道它在应用程序代码中的长度。

在表中,我有一个类型为jsonb的字段,我需要将其设置为json对象,其中键是给定数组中的值,而值都相同和等于当前时间戳,即

| id | my_field                                         |
---------------------------------------------------------
| 1  | {"a":"1544605046.21065", "b":"1544605046.21065"} |

我正在尝试查找更新查询以执行此更新,例如像

UPDATE mytable 
SET my_field = some_function(ARRAY['a','b']::text[], EXTRACT(EPOCH FROM CURRENT_TIMESTAMP)
WHERE <some_condition>;

我正在研究jsonb_build_object函数,如果我可以转换数组并将其元素与当前时间戳进行交织,这可能会对我有帮助,但是我没有找到一种方法。

请注意,我可能有数十万条记录要更新,因此我正在寻找一种快速实施的方法。

对于在此问题上的任何建议,我将不胜感激。

2 个答案:

答案 0 :(得分:1)

demo:db<>fiddle

UPDATE my_table
SET my_field = s.json_data
FROM (
    SELECT jsonb_object_agg(key, extract(epoch from current_timestamp)) as json_data
    FROM unnest(array['a', 'b']) as u(key)
) s
WHERE <some condition>
  1. 要使用array元素作为json对象的键,您需要将它们嵌套。这样会为每个元素创建一行。
  2. 使用jsonb_object_agg(key, value)聚合行。作为关键,您要使用数组元素列。作为值current_timestamp。该函数将汇总为您期望的语法。
  3. 将其放入子查询中可以进行更新。

答案 1 :(得分:0)

使用jsonb_object_agg()作为数组的未嵌套元素作为键:

select jsonb_object_agg(key, extract(epoch from current_timestamp))
from unnest(array['a', 'b']) as u(key)

                jsonb_object_agg                
------------------------------------------------
 {"a": 1544607022.84596, "b": 1544607022.84596}
(1 row)

由于UPDATE中不允许使用聚合函数,因此您应该创建一个简单的函数:

create or replace function my_arr_to_jsonb(text[])
returns jsonb language sql immutable as $$
    select jsonb_object_agg(key, extract(epoch from current_timestamp))
    from unnest($1) as u(key)
$$;

-- example use:
update my_table
set my_field = my_arr_to_jsonb(array['a', 'b'])
where id = 1;