Создание значения JSON в Postgres SQL из инструкции GROUP BY

#json #postgresql

#json #postgresql

Вопрос:

Я хочу создать один объект JSON для каждого сгруппированного поля и пытаюсь использовать json_build_object для этой цели. Однако вместо этого возвращается несколько значений json.

Ниже приведен код

 with t(product, key, value) as 
(
    values 
    ('A','category', 'food'),
    ('A','price', '4.00'),
    ('B','category', 'book'),
    ('B','price', '20.00'),
    ('B','genre', 'Sci-Fi')
)
select product, json_build_object(key, value) from t
group by product, key, value
  

и полученный результат

 "A" | "{""price"" : ""4.00""}"
"A" | "{""category"" : ""food""}"
"B" | "{""genre"" : ""Sci-Fi""}"
"B" | "{""category"" : ""book""}"
"B" | "{""price"" : ""20.00""}"
  

В результате я хочу, чтобы

 "A" | "{ 'price' : 4.00, 'category': 'food' }"
"B" | "{ 'genre' : 'Sci-Fi', 'category': 'book', 'price': 20.00 }"
  

Ответ №1:

Это то, что jsonb_object_agg() для:

 select product, jsonb_object_agg(key, value) 
from t
group by product
  

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

Ответ №2:

Вы также можете сделать это с json_object помощью и array_agg :

 with t(product, key, value) as 
(
    values 
    ('A','category', 'food'),
    ('A','price', '4.00'),
    ('B','category', 'book'),
    ('B','price', '20.00'),
    ('B','genre', 'Sci-Fi')
)
select product, json_object(array_agg(key), array_agg(value)) from t
group by product;

 product |                       json_object                        
--------- -----------------------------------------------------------
 A       | {"price": "4.00", "category": "food"}
 B       | {"genre": "Sci-Fi", "price": "20.00", "category": "book"}
(2 rows)