【问题标题】:Selecting sepecific value from json string in postgres从 postgres 中的 json 字符串中选择特定值
【发布时间】:2021-06-16 15:32:16
【问题描述】:

我正在研究一种以 JSON 字符串形式存储在数据库中的数据结构。我正在使用 postgres 数据库。
我有一个名为 usersettings 的表。里面有两列。
一列是 id(主键并自动递增),另一列是设置(输入文本)。

设置列包含 JSON 格式的数据(参见下面的示例)

{
   "SUBJECTS":[
      "Maths","Physics"
   ],
   "NAME":[
      "Thomas"
   ],
   "EMAIL_ADDRESS":"abc@xyz.com",
   "CITY":[
      "Newyork"
   ],
   "USER_ID":3,
   "TYPE":[
      "Secondary"
   ]
}

这里,json数据包含json数组。我需要一个 select sql 查询,使用它我只能获取那些包含特定 USER_ID(在上面的示例中为 3)并且其主题包含数学的行。

【问题讨论】:

  • 你很不走运,因为un-supported Postgres 9.1 版根本没有任何 JSON 支持。在没有任何内置函数的情况下解析 JSON 将是一场噩梦。在继续之前,请升级到最新的 Postgres 版本(12、13)
  • 除了升级到更新版本的 postgres 之外,你还应该确保使用 jsonb 类型。 jsonb 支持许多 json 不支持的操作。 postgresql.org/docs/13/functions-json.html

标签: java sql json postgresql postgresql-9.1


【解决方案1】:

假设您已升级到 Postgres 版本 (12, 13),您可以使用递归 CTE 将每行的 JSON 结构展平,将每行设置的用户 ID 与“主题”数组中的每个项目相关联“ 钥匙。然后,可以使用带有exists 的子查询来查找以“数学”为主题的用户 ID:

with recursive cte(uid, js, subject, sid) as (
    select u.settings::json -> 'USER_ID', u.settings, (u.settings::json -> 'SUBJECTS')::json ->> 0, 1 from usersettings u
    union all
    select c.uid, c.js, (c.js::json -> 'SUBJECTS'):: json ->> c.sid, c.sid+1 from cte c where c.sid < json_array_length(c.js::json -> 'SUBJECTS')
),
results(id, subject) as (select uid::TEXT, subject from cte)
select distinct r1.id from results r1 where exists (select 1 from results r2 where r2.id = r1.id and r2.subject = 'Maths');

输出:

id
3

demo

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-08
    • 2016-06-25
    • 2017-08-10
    • 2021-10-24
    • 2016-01-06
    • 1970-01-01
    • 2021-10-27
    • 2017-06-06
    相关资源
    最近更新 更多