我正在使用PostgreSQL 10.6。
我的表有一个jsonb列travel
,其中填充了以下示例数据。下面是sqlfiddle;
http://sqlfiddle.com/#!17/e52ff/1
我的桌子:
id | travel
-: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 | {"name": "Lucy", "trips": [{"city": "Tokyo", "continent": "Asia"}, {"city": "Bangkok", "continent": "Asia"}, {"city": "Paris", "continent": "Europe"}, {"city": "London", "continent": "Europe"}]}
2 | {"name": "Tom", "trips": [{"city": "Tokyo", "continent": "Asia"}, {"city": "Kyoto", "continent": "Asia"}, {"city": "Frankfurt", "continent": "Europe"}, {"city": "London", "continent": "Europe"}]}
3 | {"name": "Lenny", "trips": [{"city": "Tokyo", "continent": "Asia"}, {"city": "Bangkok", "continent": "Asia"}, {"city": "New York", "continent": "America"}, {"city": "Seattle", "continent": "America"}]}
DDL并插入代码:
create table people (
id serial primary key,
travel jsonb
);
insert into people (travel) values (
'{
"name": "Lucy",
"trips": [
{
"continent": "Asia",
"city": "Tokyo"
},
{
"continent": "Asia",
"city": "Bangkok"
},
{
"continent": "Europe",
"city": "Paris"
},
{
"continent": "Europe",
"city": "London"
}
]
}
'::jsonb);
insert into people (travel) values (
'{
"name": "Tom",
"trips": [
{
"continent": "Asia",
"city": "Tokyo"
},
{
"continent": "Asia",
"city": "Kyoto"
},
{
"continent": "Europe",
"city": "Frankfurt"
},
{
"continent": "Europe",
"city": "London"
}
]
}
'::jsonb);
insert into people (travel) values (
'{
"name": "Lenny",
"trips": [
{
"continent": "Asia",
"city": "Tokyo"
},
{
"continent": "Asia",
"city": "Bangkok"
},
{
"continent": "America",
"city": "New York"
},
{
"continent": "America",
"city": "Seattle"
}
]
}
'::jsonb);
我如何查询在亚洲大陆上带有“ o” 字母的城市的旅行?
感谢与问候
答案 0 :(得分:1)
我认为您自己的答案就可以了。数组选择可以稍微简化一些,大陆筛选条件的重复也很难看-我可能会写
SELECT *
FROM (
SELECT
travel -> 'name' as name,
ARRAY(
SELECT mytrips
FROM jsonb_array_elements(travel -> 'trips') mytrips
WHERE mytrips ->> 'continent' = 'Europe'
) as trips
FROM
people
) t
WHERE
trips <> '{}'
(online demo)
另一方面,如果确实在travel
上有索引,则@>
子句中的WHERE
运算符可能会更快。
可能更简单,但是对于同一个人的多次旅行而言,具有不同的语义是一种分组方法:
SELECT travel -> 'name' as name, jsonb_agg(trip) as trips
FROM people, jsonb_array_elements(travel -> 'trips') trip
WHERE trip ->> 'continent' = 'Europe'
GROUP BY name
答案 1 :(得分:0)
我不清楚您的预期输出是多少。但是要在o
中找到Asia
的城市就像这样:
SELECT
*
FROM
people,
jsonb_array_elements(travel -> 'trips') elems
WHERE
elems ->> 'city' LIKE '%o%'
AND elems ->> 'continent' = 'Asia'
continent
和city
过滤答案 2 :(得分:0)
我可以通过以下查询获得所需的结果。但是,我不确定在性能方面是否最佳。有任何建议使其性能更好吗?
SELECT
travel -> 'name',
Array(
(SELECT elements.mytrips FROM
(SELECT jsonb_array_elements(travel -> 'trips') as mytrips) as elements
WHERE elements.mytrips ->> 'continent' = 'Europe'
)
)
FROM
people
WHERE
travel -> 'trips' @> '[{"continent": "Europe"}]'