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

У меня есть следующие данные в таблице postgres,

enter image description here

где data - столбец jsonb. Я хотел бы получить результат как

[
 {field_type: "Design", briefings_count: 1, meetings_count: 13}, 
 {field_type: "Engineering", briefings_count: 1, meetings_count: 13}, 
 {field_type: "Data Science", briefings_count: 0, meetings_count: 3}
]

Ответы [ 2 ]

0 голосов
/ 04 сентября 2018

Объяснение

Используйте функцию jsonb_each_text для извлечения данных из jsonb столбца с именем data. Затем агрегируйте строки, используя GROUP BY, чтобы получить одну строку для каждого отдельного field_type. Для каждой агрегации нам также необходимо включить количество встреч и брифингов, которое выбирается путем выбора максимального значения с учетом случая, чтобы можно было создать два отдельных столбца для разных количеств. Кроме того, примените функцию coalesce, чтобы вернуть 0 вместо NULL, если какая-то информация отсутствует - в вашем примере это будут брифинги для Data Science.

На более высоком уровне утверждения теперь, когда у нас есть результаты в виде таблицы с полями, нам нужно построить объект jsonb и объединить их все в одну строку. Для этого мы используем jsonb_build_object, в который передаем пары, состоящие из: имя поля + значение. Это дает нам 3 строки данных, каждая из которых имеет отдельный столбец jsonb с данными. Так как нам нужен только один ряд (агрегированный json) в выводе, нам нужно применить jsonb_agg поверх этого. Это приносит нам результат, который вы ищете.

Код

Проверьте LIVE DEMO , чтобы увидеть, как это работает.

select
  jsonb_agg(
    jsonb_build_object('field_type', field_type,
                     'briefings_count', briefings_count,
                     'meetings_count', meetings_count
                     )
    ) as agg_data
from (
  select
      j.k as field_type
    , coalesce(max(case when t.count_type = 'briefings_count' then j.v::int end),0) as briefings_count
    , coalesce(max(case when t.count_type = 'meetings_count'  then j.v::int end),0) as meetings_count
  from tbl t, 
       jsonb_each_text(data) j(k,v)
  group by j.k
  ) t
0 голосов
/ 04 сентября 2018

Вы можете объединить столбцы, подобные этим, и затем вставить данные в другую таблицу

select array_agg(data)
from the_table

Или используйте одну из встроенных функций json для создания нового массива json. Например jsonb_agg (выражение)

...