从对象JSONB中的数组中删除元素

时间:2017-02-17 13:21:50

标签: postgresql jsonb

我正在尝试从数据库中删除一个元素。我想删除的元素位于名为playerContainer的JSON对象中,该对象包含一个名为players的数组。这一切都在一个名为site_content的表中。我试图根据它的ID删除对象,但是我收到了这个错误。

  

删除元素                       来自site_content,                       横向jsonb_array_elements(内容 - >' playersContainer' - >'球员')elem                       其中elem @> ' {" ID":" 22"}'
             因为:错误:语法错误在或附近" elem"职位:27

以下是我的查询,谁能看到我哪里出错了?

DELETE elem 
from site_content, 
lateral jsonb_array_elements(content->'playersContainer'->'players') elem 
where elem @> '{"id":"1"}' 

以下是示例JSON

"playersContainer": {
        "players": [
            {
                "id": "1",
                "name": "Nick",
                "teamName": "Shire Soldiers",
                "ratings": [
                    1,
                    5,
                    6,
                    9
                ],
                "assists": 17,
                "manOfTheMatches": 20,
                "cleanSheets": 1,
                "data": [
                    3,
                    2,
                    3,
                    5,
                    6
                ],
                "totalGoals": 19

            },
}

1 个答案:

答案 0 :(得分:2)

DELETE适用于表格的行。因此,除非您要删除整行,否则无法使用它。

试试这个:

create temp table testing as
select 
    '{ "playersContainer": {
        "players": [
            {
                "id": "1",
                "name": "Nick"
            },
            {
                "id": "2",
                "name": "Rick"
            },
            {
                "id": "3",
                "name": "Trick"
            }
        ]
     }}'::jsonb as value;

现在你需要找到你想要删除的玩家的位置,假设你想要Rick的id为2(因为索引从0开始减1)

select position-1 from testing, jsonb_array_elements(value->'playersContainer'->'players') with ordinality arr(elem, position) WHERE elem->>'id' = '2';

现在,您可以将其与UPDATE语句结合使用以更新字段。使用减号( - )运算符删除所需索引处的元素。

UPDATE testing SET value = jsonb_set(value, '{playersContainer,players}', (value->'playersContainer'->'players') - (select position-1 from testing, jsonb_array_elements(value->'playersContainer'->'players') with ordinality arr(elem, position) WHERE elem->>'id' = '2')::int );

最终结果:

{
    "playersContainer":{
        "players":[
            {
                "id":"1",
                "name":"Nick"
            },
            {
                "id":"3",
                "name":"Trick"
            }
        ]
    }
}