从json访问列表并在postgres中迭代

时间:2018-05-30 05:34:32

标签: postgresql-9.6

我有一个如下所述的json,

{
    "list": [{
            "notificationId": 123,
            "userId": 444
        },
        {
            "notificationId": 456,
            "userId": 789
        }
    ]
}

我需要编写一个postgres过程,该过程通过列表进行交互,并根据通知ID执行更新/插入已经存在或不存在于DB中。

我有一个通知表,其中包含notificationid和userID作为列。

任何人都可以告诉我如何使用postgres json运算符执行此操作。

3 个答案:

答案 0 :(得分:0)

尝试此查询:

SELECT *
FROM yourTable
WHERE col->'list'@>'[{"notificationId":123}]';

您可以将值123替换为您要搜索的notificationId。请点击以下链接查看显示此逻辑的演示:

Demo

答案 1 :(得分:0)

假设您对notificationid有唯一约束(例如因为它是主键,则不需要存储函数或循环:

with data (j) as (
  values ('
  {
      "list": [{
              "notificationId": 123,
              "userId": 444
          },
          {
              "notificationId": 456,
              "userId": 789
          }
      ]
  }'::jsonb)
)
insert into notification (notificationid, userid)
select (e.r ->> 'notificationId')::int, (e.r ->> 'userId')::int
from data d, jsonb_array_elements(d.j -> 'list') as e(r)
on conflict (notificationid) do update
   set userid = excluded.userid;

该语句的第一步是将数组转换为行列表,这是:

select e.*
from data d, jsonb_array_elements(d.j -> 'list') as e(r)

一样。给定样本JSON,这将返回两行,每行包含一个JSON值:

r                                     
--------------------------------------
{"userId": 444, "notificationId": 123}
{"userId": 789, "notificationId": 456}

然后将其拆分为两个整数列:

select (e.r ->> 'notificationId')::int, (e.r ->> 'userId')::int
from data d, jsonb_array_elements(d.j -> 'list') as e(r)

所以我们得到:

int4 | int4
-----+-----
 123 |  444
 456 |  789

此结果用作INSERT语句的输入。

on conflict子句然后执行插入或更新,具体取决于列notificationid标识的行的存在,该列必须具有唯一索引。

答案 2 :(得分:0)

同时我试过这个,

onNewIntent

它有效..请回顾一下。