Как сгруппировать по столбцу, объединить массив по другому и создать один объект JSON, связанный с помощью сгруппированного столбца - PullRequest
0 голосов
/ 12 декабря 2018

С этим запросом и набором записей:

SELECT id, level FROM t;

id | level
----------
1  | a 
2  | a 
3  | a 
4  | b 
5  | b 
6  | c
7  | c

Как преобразовать это в объект JSON, основанный на столбце уровня и массиве, агрегированном в столбце идентификатора?Я не знаю заранее, какие уровни существуют.

{
  "a": [1, 2, 3],
  "b": [4, 5],
  "c": [6, 7]
}

Я надеялся сделать это:

SELECT json_object(
  array_agg(level),
  array_agg(ids)
)
FROM (
  SELECT level, array_agg(id::TEXT) ids
  FROM t
  GROUP BY level
) t

Но он возвращает:

ОШИБКА:не может накапливать массивы разной размерности

Если вы хотите ответить, вот t для вашего удобства

SELECT id, level
FROM ( VALUES
  (1, 'a'),
  (2, 'a'),
  (3, 'a'),
  (4, 'b'),
  (5, 'b'),
  (6, 'c'),
  (7, 'c')
) t(id, level);

1 Ответ

0 голосов
/ 12 декабря 2018

Используйте json (b) агрегатные функции:

with my_table(id, level) as (
values
    (1, 'a'),
    (2, 'a'),
    (3, 'a'),
    (4, 'b'),
    (5, 'b'),
    (6, 'c'),
    (7, 'c')
)
select jsonb_object_agg(level, ids)
from (
    select level, jsonb_agg(id) as ids
    from my_table
    group by level
    ) s

              jsonb_object_agg              
--------------------------------------------
 {"a": [1, 2, 3], "b": [4, 5], "c": [6, 7]}
(1 row) 
...