我的数据库包含一个包含列foo
的表id
和一个包含以下数据的列data
:
{
"startDate":"2017-07-04",
"endDate":"2017-07-10",
"notDelegated":false,
"sold":false,
"disableRanking":false,
"type":"PERIOD"
}
我想用父rangeData
更新此数据并提取type
属性,如下所示:
{
"rangeData": {
"startDate":"2017-07-04",
"endDate":"2017-07-10",
"notDelegated":false,
"sold":false,
"disableRanking":false
},
"type":"PERIOD"
}
我尝试使用JSON
运算符做了很多事情。
感谢您的回答。
答案 0 :(得分:1)
使用函数jsonb_build_object()
并删除运算符:
update foo
set data = jsonb_build_object('rangeData', data- 'type', 'type', data->'type');
在上面的函数调用中,您将创建一个包含两个元素的json对象:
key value
-------------------------
'rangeData' data- 'type' json object 'data' from which the key 'type' was removed
'type' data->'type' value of 'type' element of json object 'data'
答案 1 :(得分:0)
您可以使用jsonb_set(target jsonb, path text[], new_value jsonb[, create_missing boolean])
(请参阅the docs)。
它不是很漂亮,但是我这样做了(你可以自己运行SQLFiddle我自己运行):
SELECT
jsonb_set(
(final.range_data):: jsonb,
'{type}',
to_jsonb(final.type)
)
FROM
(
SELECT
jsonb_set(
jsonb '{}', '{rangeData}', fields.range_data
) AS range_data,
fields.type AS type
FROM
(
SELECT
data.jsonb - 'type' AS range_data,
data.jsonb ->> 'type' AS type
FROM
(
SELECT
'{"startDate":"2017-07-04","endDate":"2017-07-10","notDelegated":false,"sold":false,"disableRanking":false,"type":"PERIOD"}' :: jsonb
) data
) fields
) final;
这将为您提供以下的jsonb输出:
{"rangeData": {"startDate":"2017-07-04","endDate":"2017-07-10","notDelegated":false,"sold":false,"disableRanking":false},"type":"PERIOD"}
所以你最终会做类似的事情:
UPDATE
foo
SET
data = (
SELECT
jsonb_set(
(final.range_data):: jsonb,
'{type}',
to_jsonb(final.type)
)
FROM
(
SELECT
jsonb_set(
jsonb '{}', '{rangeData}', fields.range_data
) AS range_data,
fields.type AS type
FROM
(
SELECT
data.jsonb - 'type' AS range_data,
data.jsonb ->> 'type' AS type
FROM
(
SELECT
foo.data
) data
) fields
) final
);
我没有运行最终的UPDATE
查询,但我确实运行了天真的SELECT
语句,它按预期输出了我的输出。
另外,请注意,我是SQL的新手(特别是jsonb的东西),所以我相信会有更高性能和/或更正确的“jsonb-like”方式来做到这一点。取决于您的用例(如果是一次性迁移,或者如果您需要在每次实时阅读中执行此操作等)。