Получить значения, отфильтрованные по ключу jsonb - PullRequest
0 голосов
/ 08 февраля 2019

У меня есть таблица с именем houses, в которой есть столбец jsonb с именем details.Структура столбца details jsonb:

{
  owner_id: TEXT,
  owner_name: TEXT,
  offers: [{ offer_id: TEXT, offer_value_id: TEXT, offer_value_name: TEXT }]
}

Обратите внимание, что иногда предложения могут быть совершенно пустыми, например, offers: []

Итак, сейчас у меня есть запрос, которыйПозвольте мне получить всех отдельных владельцев домов, заказанных owner_name.Это выглядит так:

SELECT distinct ("details"->>'owner_id') as "identifier", "details"->>'owner_name' as "name" 
FROM houses 
order by "details"->>'owner_name' asc 

Я хочу сделать что-то похожее, но теперь я хочу получить все различные значения предложения, но только для конкретного offer_id.Ниже приведены некоторые примеры данных, но я ожидал:

id, подробности

1, { owner_id: '1', owner_name: 'john', offers: [] }
2, { owner_id: '2', owner_name: 'charles', offers: [ { offer_id: '1', offer_value_id: '1', offer_value_name: 'offer1'}, { offer_id: '2', offer_value_id: '2', offer_value_name: 'offer2'}] }
3, { owner_id: '3', owner_name: 'melissa', offers: [ { offer_id: '2', offer_value_id: '5', offer_value_name: 'a offer 3'} ]
4, { owner_id: '3', owner_name: 'melissa', offers: [ { offer_id: '6', offer_value_id: '8', offer_value_name: 'offer10'} ]

Итак, скажем, я хочу получить все разные идентификаторы значений предложений и имена значений, когда offer_id'2'.Результат будет:

identifier (this would be offer_value_id), name (this would be offer_value_name)
'5', 'a offer 3'
'2', 'offer2'
null, null

Обратите внимание, что есть null, null, потому что есть по крайней мере две строки, у которых нет предложений, где offer_id равен 1, и я хочуполучить это тоже.Также обратите внимание, что значения упорядочены по offer_value_name NULL, являющимся последними.

Я пробовал следующее, но не работает:

SELECT distinct ("details"->>'offers'->>'offer_value_id') as "identifier", ("details"->>'offers'->>'offer_value_name') as "name" 
    FROM houses 
    WHERE "details"->>'offers'->>'offer_id' = '2'
    order by "details"->>'offers'->>'offer_value_name' asc 

И я не думаю, что этот подходбудет работать, потому что, если в подробных предложениях нет offer_id, я также хочу, чтобы он выбрал NULL, это просто отфильтровывает его.

1 Ответ

0 голосов
/ 08 февраля 2019

Я думаю, что это сработает:

SELECT DISTINCT "offers"->>'offer_value_id' as "identifier", "offers"->>'offer_value_name' as "name"
FROM houses
LEFT JOIN jsonb_array_elements("details"->'offers') "offers" ON "offers"->>'offer_id' = '1';
ORDER BY "offers"->>'offer_value_name' NULLS LAST

Вы знаете, что хотите получить все записи независимо от того, существует это предложение с идентификатором 1 или нет, поэтому вы делаете ЛЕВОЕ СОЕДИНЕНИЕ.

Другая вещь, на которую следует обратить внимание, это jsonb_array_elements, которая полезна, потому что она расширяет этот json до набора значений json.Таким образом, вы можете получить доступ к offers, как если бы это было поле верхнего уровня.

...