2015-07-22 4 views
1

У меня есть следующая таблица:Как вернуть массив объектов из jsonb?

CREATE TABLE mytable (
    id  serial PRIMARY KEY 
, employee text UNIQUE NOT NULL 
, data  jsonb 
); 

со следующими данными:

INSERT INTO mytable (employee, data) 
VALUES 
('Jim', '{"sales_tv": [{"value": 10, "yr": "2010", "loc": "us"}, {"value": 5, "yr": "2011", "loc": "europe"}, {"value": 40, "yr": "2012", "loc": "asia"}], "sales_radio": [{"value": 11, "yr": "2010", "loc": "us"}, {"value": 8, "yr": "2011", "loc": "china"}, {"value": 76, "yr": "2012", "loc": "us"}], "another_key": "another value"}'), 
('Rob', '{"sales_radio": [{"value": 7, "yr": "2014", "loc": "japan"}, {"value": 3, "yr": "2009", "loc": "us"}, {"value": 37, "yr": "2011", "loc": "us"}], "sales_tv": [{"value": 4, "yr": "2010", "loc": "us"}, {"value": 18, "yr": "2011", "loc": "europe"}, {"value": 28, "yr": "2012", "loc": "asia"}], "another_key": "another value"}') 

Обратите внимание, что существуют и другие ключи в там помимо всего "sales_tv" и "sales_radio". Для запросов ниже мне просто нужно сосредоточиться на «sales_tv» и «sales_radio».

Я пытаюсь вернуть список объектов для Джима для всего, что начинается с «sales_». В каждом объекте ш/в списке Мне просто нужно, чтобы вернуть значение и YR (без учета «местоположение» или любые другие ключи), например:

employee | sales_ 
    Jim  | {"sales_tv": [{"value": 10, "yr": "2010"}, {"value": 5, "yr": "2011"}, {"value": 40, "yr": "2012"}], 
       "sales_radio": [{"value": 11, "yr": "2010"}, {"value": 8, "yr": "2011"}, {"value": 76, "yr": "2012"}]} 

Я могу получить каждое из значений, но без года ни формат список я хотел бы:

SELECT t.employee, json_object_agg(a.k, d.value) AS sales 
FROM mytable t 
    , jsonb_each(t.data)  a(k,v) 
    , jsonb_to_recordset(a.v) d(yr text, value float) 
WHERE t.employee = 'Jim' 
AND a.k LIKE 'sales_%' 
GROUP BY 1 

результатов:

employee | sales 
---------- | -------- 
Jim   | { "sales_tv" : 10, "sales_tv" : 5, "sales_tv" : 40, "sales_radio" : 11, "sales_radio" : 8, "sales_radio" : 76 } 

ответ

0

принцип такой же, как the question you asked yesterday, первый запрос (даже если этот вопрос вчерашнего второго запроса): очистите слои иерархии в своих данных json, а затем повторно соберите их с любыми данными, которые вас интересуют, в любой новый формат json.

SELECT employee, json_object_agg(k, jarr) AS sales 
FROM (
    SELECT t.employee, a.k, 
     json_agg(json_build_object('value', d.value, 'yr', d.yr)) AS jarr 
    FROM mytable t, 
     jsonb_each(t.data) a(k, v), 
     jsonb_to_recordset(a.v) d(yr text, value float) 
    WHERE t.employee = 'Jim' 
    AND a.k like 'sales_%' 
    GROUP BY 1, 2) sub 
GROUP BY 1; 

В пункте FROM вы ломаете вниз по иерархии JSON с функциями, как jsonb_each и jsonb_to_recordset. Как уже упоминалось в имени последней функции, каждый из них создает набор записей, с которыми вы можете работать, как и с любой другой таблицей и ее столбцами. В списке выбора столбца вы выбираете необходимые данные и соответствующие функции агрегата json_agg и json_object_agg, чтобы вернуть результат JSON вместе. Для каждого уровня иерархии вам нужна одна агрегированная функция и, следовательно, один уровень подзапроса.

Смежные вопросы