У меня есть случай, когда мои данные во вложенных массивах jsonb, чтобы найти значение, мне нужно сделать несколько JSONB_ARRAY_ELEMENTS, что является дорогостоящим и требует много вложенного кода.
Файл json имеет континенты внутри стран и внутри городов. Мне нужно получить доступ к значению города.
- Есть ли способ сделать этот запрос проще и быстрее?
- Я пытался решить его, используя JSON_EXTRACT_PATH, но чтобы попасть в массив, но мне нужны индексы.
WITH mydata AS (
SELECT '
{
"continents":[
{
"name":"America",
"area":43316000,
"countries":[
{
"country_name":"Canada",
"capital":"Toronto",
"cities":[
{
"city_name":"Ontario",
"population":2393933
},
{
"city_name":"Quebec",
"population":12332
}
]
},
{
"country_name":"Brazil",
"capital":"Brasilia",
"cities":[
{
"city_name":"Sao Paolo",
"population":34534534
},
{
"city_name":"Rio",
"population":445345
}
]
}
]
},
{
"name":"Europa",
"area":10530751,
"countries":[
{
"country_name":"Switzerland",
"capital":"Zurich",
"cities":[
{
"city_name":"Ginebra",
"population":4564565
},
{
"city_name":"Basilea",
"population":4564533
}
]
},
{
"country_name":"Norway",
"capital":"Oslo",
"cities":[
{
"city_name":"Oslo",
"population":3243534
},
{
"city_name":"Steinkjer",
"population":4565465
}
]
}
]
}
]
}
'::JSONB AS data_column
)
SELECT cit.city->>'city_name' AS city,
(cit.city->>'population')::INTEGER AS population
FROM (SELECT JSONB_ARRAY_ELEMENTS(coun.country->'cities') AS city
FROM (SELECT JSONB_ARRAY_ELEMENTS(cont.continent->'countries') AS country
FROM (SELECT JSONB_ARRAY_ELEMENTS(data_column->'continents') AS continent
FROM mydata
) AS cont
WHERE cont.continent @> '{"name":"Europa"}'
) AS coun
WHERE coun.country @> '{"country_name" : "Norway"}'
) AS cit
WHERE cit.city @> '{"city_name": "Oslo"}'
Видите мои вложенные запросы? выглядит некрасиво, я могу получить ответ, используя: JSONB_EXTRACT_PATH( data_column->'continents', '1', 'countries', '1', 'cities', '0', 'population')
, но мне пришлось жестко закодировать индексы массива.
Надеюсь, вы мне поможете.
Спасибо.