从同一表中的其他列更新JSONB列数据

时间:2018-08-07 01:47:32

标签: json postgresql sql-update jsonb

Postgres 9.5 中,我想用同一表中其他列的数据更新一列。问题与""符号有关,因为在JSON字符串中不允许从实际列读取数据:

CREATE TABLE sample_table(
   id bigint
 , revision integer
 , var_data text
 , json_result jsonb
);

样本数据:

id  revision  var_data  json_result
1     10        test_A   {"EstimatedResult": 10, "RevOnly": 10}
2     20        test_B   {"EstimatedResult": 20, "RevOnly": 20}
3     30        test_C   {"EstimatedResult": 30, "RevOnly": 30}

示例1:正在运行:

UPDATE "public"."sample_table"
SET "json_result" = "json_result" - 'EstimatedResult'
                  || jsonb_build_object('EstimatedResult', revision::numeric)::jsonb
WHERE json_result->>'EstimatedResult' IS NOT NULL;

结果json_result

{"EstimatedResult": 10, "RevOnly": 10}
{"EstimatedResult": 20, "RevOnly": 20}
{"EstimatedResult": 30, "RevOnly": 30}

示例2:无法正常工作:

要求是修改json结构以从多个列中插入数据。结果应该是这样的:

{"EstimatedResult": {"revid": 10, "displ": "test_A"}, "RevOnly": 10}
{"EstimatedResult": {"revid": 20, "displ": "test_B"}, "RevOnly": 20}
{"EstimatedResult": {"revid": 30, "displ": "test_C"}, "RevOnly": 30}

我知道如何使用Example1从“ RevOnly”中的列中强制数据。 但是,我无法成功将列中的数据强制为“ revid”和“ displ”

我成功生成了JSON值,但是结果是这样的:

{"EstimatedResult": {"revid": "revision", "displ": "var_data"}, "RevOnly": 10}
{"EstimatedResult": {"revid": "revision", "displ": "var_data"}, "RevOnly": 20}
{"EstimatedResult": {"revid": "revision", "displ": "var_data"}, "RevOnly": 30}

注意“修订”和“ var_data”未更新。

如何正确更新?

2 个答案:

答案 0 :(得分:0)

假设至少为Postgres 9.5 ,并且数据类型为 jsonb
jsonb_set()是一种优雅的方法-与您已经成功使用的jsonb_build_object()结合使用:

SELECT jsonb_set(json_result
              , '{EstimatedResult}'
              , jsonb_build_object('revid', revision, 'displ', var_data))
FROM   sample_table;

答案 1 :(得分:0)

UPDATE命令完全符合我的要求。
万一有人需要它。

UPDATE public.sample_table SET json_result =
       jsonb_set(json_result
               , '{EstimatedResult}'
               , jsonb_build_object('revid', revision::numeric, 'displ', var_data::text)) 
 WHERE json_result->>'EstimatedResult' IS NOT NULL
 RETURNING *;