Mât*_*man 9 postgresql json psql postgresql-9.3
使用postgresql 9.3(以及新的json awesomness)如果我有一个名为'races'的简单表,其中包含两列描述,例如:
race-id integer,
race-data json
Run Code Online (Sandbox Code Playgroud)
而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 }
Run Code Online (Sandbox Code Playgroud)
如何查询表格:
1)第一场比赛的比赛
2)山姆赛季排名第一,约翰排名第二
3)年龄大于30岁的跑步者数> 5且奖金> 5000
到目前为止,我的实验(特别是在查询嵌套数组有效负载时)导致数据进一步规范化,即创建一个名为runners的表来进行此类查询.理想情况下,我想使用这个新的fangled json查询真棒,但我似乎无法在3个简单查询中分别对应它.
Rom*_*kar 14
您可以将json展开到一个记录中,然后根据需要进行查询(请参阅json函数):
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'
Run Code Online (Sandbox Code Playgroud)
由于你的JSON结构,它有点复杂.我认为如果你稍微改变一下你的结构,你的查询可能会简单得多:
{
"race-time": some-date,
"runners":
{
"1": {"name": "fred","age": 30},
"2": {"name": "sam","age": 31},
"3": {"name": "john","age": 29}
},
"prize-money": 200
}
Run Code Online (Sandbox Code Playgroud)
您可以使用->>和->运算符或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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4441 次 |
| 最近记录: |