Выберите элементы из массива jsonb в postgres 12 - PullRequest
0 голосов
/ 04 мая 2020

Я пытаюсь извлечь элементы из столбца JSONB. У меня есть таблица типа:

id NUMBER
data JSONB

структура данных:

[{
    "id": "abcd",
    "validTo": "timestamp"
}, ...]

Я запрашиваю эту строку с помощью SELECT * FROM testtable WHERE data @> '[{"id": "abcd"}]', и она почти работает так, как я хочу.

Беда в том, что столбец data огромен, например, 100 тыс. Записей, поэтому я хотел бы получить только те элементы данных, которые мне нужны. Например, если бы я запросил SELECT * FROM testtable WHERE data @> '[{"id": "abcd"}]' OR data @> '[{"id": "abcde"}]', я ожидаю, что столбец данных будет содержать только записи с идентификатором abcd или abcde. Вот так:

[
{"id": "abcd"},
{"id": "abcde"}
]

Было бы хорошо, если бы запрос возвращал отдельные записи с одной записью данных.

У меня нет идей, как ее решить, пробуя варианты лотов с дней.

Ответы [ 3 ]

0 голосов
/ 04 мая 2020

Не совсем понял ваш вопрос. Вы спрашиваете, что ответ должен содержать только столбец данных без столбца идентификатора. Затем я думаю, что это запрос: '' 'code "' Выберите данные из тестовой таблицы, где id =" abcd " или id = "abcde"; "'code' ''

0 голосов
/ 04 мая 2020

Для отдельного вывода для записей, имеющих несколько совпадений

with a (id, data) as (
  values
    (1, '[{"id": "abcd", "validTo": 2}, {"id": "abcde", "validTo": 4}]'::jsonb),
    (2, '[{"id": "abcd", "validTo": 3}, {"id": "abc", "validTo": 6}]'::jsonb),
    (3, '[{"id": "abc", "validTo": 5}]'::jsonb)
)
select id, jsonb_array_elements(jsonb_path_query_array(data, '$[*] ? (@.id=="abcd" || @.id=="abcde")'))
from a;

0 голосов
/ 04 мая 2020

Вам нужно будет откатить, отфильтровать и агрегировать обратно:

select t.id, j.*
from testtable t
  join lateral (
     select jsonb_agg(e.x) as data
     from jsonb_array_elements(t.data) as e(x)
     where e.x @> '{"id": "abcd"}'
        or e.x @> '{"id": "abcde"}'
  ) as j on true

Онлайн пример

С Postgres 12 вы можете использовать jsonb_path_query_array() в качестве альтернатива, но для этого потребуется повторить условия:

select t.id,
       jsonb_path_query_array(data, '$[*] ? (@.id == "abcd" || @.id == "abcde")')
from testtable t
where t.data @> '[{"id": "abcd"}]'
   or t.data @> '[{"id": "abcde"}]'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...