json - 在 9.3+ 中查询嵌套负载的 Postgresql json

标签 json postgresql psql postgresql-9.3

使用 postgresql 9.3(和新的 json awesomne​​ss)如果我有一个名为“races”的简单表,其中包含两列描述,例如:

race-id integer,
race-data json

而 json 是每场比赛的有效载荷,类似于

{      "race-time": some-date,
  "runners": [ { "name": "fred","age": 30, "position": 1 },
               { "name": "john","age": 29, "position": 3 },
               { "name": "sam","age": 31, "position": 2 } ],
  "prize-money": 200    }

如何查询表:

1) sam 获得第一名的比赛

2) sam 获得第一名而 john 获得第二名的比赛

3) 30岁以上参赛人数>5人且奖金>5000

到目前为止,我的实验(特别是在查询嵌套数组有效载荷方面)导致进一步规范化数据,即创建一个名为 runners 的表来进行此类查询。理想情况下,我想使用这个新的奇特的 json 查询功能,但我似乎无法对 3 个简单查询做出正面或反面的判断。

最佳答案

您可以展开 json 到一条记录中,然后根据需要进行查询(参见 json functions):

with cte as (
    select
       race_id,
       json_array_elements(r.race_data->'runners') as d,
       (r.race_data->>'prize-money')::int as price_money
    from races as r
), cte2 as (
    select
        race_id, price_money,
        max(case when (d->>'position')::int = 1 then d->>'name' end) as name1,
        max(case when (d->>'position')::int = 2 then d->>'name' end) as name2,
        max(case when (d->>'position')::int = 3 then d->>'name' end) as name3
    from cte
    group by race_id, price_money
)
select *
from cte2
where name1 = 'sam' and name2 = 'john'

sql fiddle demo

由于您的 JSON 结构,它有点复杂。我认为如果您稍微改变一下结构,您的查询可能会简单得多:

{
  "race-time": some-date,
  "runners":
   {
      "1": {"name": "fred","age": 30},
      "2": {"name": "sam","age": 31},
      "3": {"name": "john","age": 29}
   },
  "prize-money": 200
}

你可以使用->>->运算符或者json_extract_path_text函数来获取你需要的数据,然后在中使用它>where 子句:

select *
from races as r
where
    r.race_data->'runners'->'1'->>'name' = 'sam';

select *
from races as r
where
    json_extract_path_text(r.race_data, 'runners','1','name') = 'sam' and
    json_extract_path_text(r.race_data, 'runners','2','name') = 'john';

select *
from races as r
where
    (r.race_data->>'prize-money')::int > 100 and
    (
        select count(*)
        from json_each(r.race_data->'runners')
        where (value->>'age')::int >= 30
    ) >= 2

sql fiddle demo

关于json - 在 9.3+ 中查询嵌套负载的 Postgresql json,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20373954/

相关文章:

php - PayPal REST API 送货地址不适用于 cURL 请求

java - Json 问号 ("??????") 而不是希伯来字符

java - 首次运行 jhipster 应用程序时出错

sql - PostgreSQL:使用 psql 命令行实用程序时 Windows 上的编码问题

postgresql - 从命令行创建数据库

javascript - 访问具有空格的 JSON 对象键

json - 如何使nodejs服务器异步

ruby-on-rails - 如何将 Evernote API 时间戳转换为 Postgresql 时间戳

PostgreSQL 相当于 MySQL --force 标志

python - Psycopg2(curr.execute)返回 NONE python