#sql #arrays #json #postgresql #lateral-join
#sql #массивы #json #postgresql #боковое соединение
Вопрос:
У меня есть таблица JSON с некоторыми объектами, и я пытаюсь запросить значение суммы в объекте
{
"authorizations": [
{
"id": "d50",
"type": "passed",
"amount": 100,
"fortId": 5050,
"status": "GENERATED",
"voided": false,
"cardNumber": 3973,
"expireDate": null,
"description": "Success",
"customerCode": "858585",
"paymentMethod": "cash",
"changeDatetime": null,
"createDatetime": 000000000,
"reservationCode": "202020DD",
"authorizationCode": "D8787"
},
{
"id": "d50",
"type": "passed",
"amount": 100,
"fortId": 5050,
"status": "GENERATED",
"voided": false,
"cardNumber": 3973,
"expireDate": null,
"description": "Success",
"customerCode": "858585",
"paymentMethod": "cash",
"changeDatetime": null,
"createDatetime": 000000000,
"reservationCode": "202020DD",
"authorizationCode": "D8787"
}
],
}
Я попробовал следующие четыре варианта, но ни один из них не дает мне значение объекта:
SELECT info @> 'authorizations:[{amount}]'
FROM idv.reservations;
SELECT info -> 'authorizations:[{amount}]'
FROM idv.reservations;
info -> ''authorizations' ->> 'amount'
FROM idv.reservations
select (json_array_elements(info->'authorizations')->'amount')::int from idv.reservations
обратите внимание, что я использую DBeaver
Ответ №1:
Если вам нужна одна строка для каждого объекта, содержащегося в массиве JSON «авторизации», с соответствующим количеством, вы можете использовать боковое соединение и jsonb_array_elements()
:
select r.*, (x.obj ->> 'amount')::int as amount
from reservations r
cross join lateral jsonb_array_elements(r.info -> 'authorizations') x(obj)
Мы также можем извлечь все суммы сразу и поместить их в массив, например:
select r.*,
jsonb_path_query_array(r.info, '$.authorizations[*].amount') as amounts
from reservations r