У меня есть столбец в базе данных PostgreSQL, который в основном представляет собой jsonified список кортежей python:
[
["Mobile","111-111-1111"],
["Office","222-222-2222"],
["Mobile","333-333-3333"],
["Fax","444-444-4444"],
]
Я хотел бы построить запрос, который возвращает подмножество списка, основанное на первом значении в каждом из вложенных списков. Ниже приведен psudo-запрос, который, надеюсь, проиллюстрирует, что мне нужно:
SELECT
foo AS bar,
(SELECT
element
FROM
phone_numbers
WHERE
element::json->>0 = "Mobile") AS mobile_numbers
FROM
db
;
mobile_numbers == [["Mobile","111-111-1111"],["Mobile","333-333-3333"]]
Я знаю только биты о json-операторах в PostgreSQL (и SQL-запросы вообще), в основном в словарях. Я могу найти много примеров здесь о том, как копать в вложенные словари и возвращать одно значение, но я не нашел ничего, что вполне соответствует тому, что мне нужно.
Спасибо за вашу помощь.
Предполагая, что столбец содержит допустимый json в качестве массива массивов, вы должны отключить внешний массив с помощью jsonb_array_elements()
, фильтровать внутренние массивы (кортежи) с помощью первого (индекс 0) своих элементов и агрегировать результаты с помощью jsonb_agg().
with my_table(phone_numbers) as (
values
('[
["Mobile","111-111-1111"],
["Office","222-222-2222"],
["Mobile","333-333-3333"],
["Fax","444-444-4444"]
]'::jsonb)
)
select jsonb_agg(phone)
from my_table
cross join jsonb_array_elements(phone_numbers) as arr(phone)
where phone->>0 = 'Mobile'
jsonb_agg
----------------------------------------------------------
[["Mobile", "111-111-1111"], ["Mobile", "333-333-3333"]]
(1 row)
cross join <function>
всегда боковое , вам не следует бояться декартового произведения, см., например, PostgreSQL json_array_elements в предложении FROM - почему это не декартово соединение?