Вложенная JSON агрегация в Postgres - PullRequest
1 голос
/ 02 февраля 2020

Мне нужно выполнить запрос к базе данных Postgres, агрегировать его и экспортировать как объект json с использованием собственного инструмента Postgres.

Я не могу получить агрегацию работает правильно, и я немного озадачен.

Ниже приведен пример некоторых данных

| msgserial |  object_type  | payload_key |                          payload                          | user_id |
+-----------+---------------+-------------+-----------------------------------------------------------+---------+
|   1696962 | CampaignEmail | a8901b2c    | {"id": "ff7221da", "brand": "MAGIC", "eventType": "SENT"} |     001 |
|   1696963 | OtherType     | b8901b2c    | {"id": "ff7221db", "brand": "MAGIC", "eventType": "SENT"} |     001 |
|   1696964 | OtherType     | c8901b2c    | {"id": "ff7221dc", "brand": "MAGIC", "eventType": "SENT"} |     002 |
|   1696965 | OtherType     | d8901b2c    | {"id": "ff7221dd", "brand": "MAGIC", "eventType": "SENT"} |     001 |
|   1696966 | CampaignEmail | e8901b2c    | {"id": "ff7221de", "brand": "MAGIC", "eventType": "SENT"} |     001 |
|   1696967 | CampaignEmail | f8901b2c    | {"id": "ff7221df", "brand": "MAGIC", "eventType": "SENT"} |     002 |
|   1696968 | SomethingElse | g8901b2c    | {"id": "ff7221dg", "brand": "MAGIC", "eventType": "SENT"} |     001 |
+-----------+---------------+-------------+-----------------------------------------------------------+---------+

Мне нужно вывести объект JSON, подобный этому, сгруппированный по user_id

{
  "user_id": 001,
  "brand": "MAGIC",
  "campaignEmails": [
    {"id": "ff7221da", "brand": "MAGIC", "eventType": "SENT"},
    {"id": "ff7221de", "brand": "MAGIC", "eventType": "SENT"},
    {"id": "ff7221de", "brand": "MAGIC", "eventType": "SENT"}
  ],
  "OtherTypes": [
    {"id": "ff7221db", "brand": "MAGIC", "eventType": "SENT"},
    {"id": "ff7221dd", "brand": "MAGIC", "eventType": "SENT"}
  ],
  "Somethingelses": [
    {"id": "ff7221dg", "brand": "MAGIC", "eventType": "SENT"}
  ]
},
{
  "user_id": 002,
  "campaignEmails": [
  ],
  "OtherTypes": [

  ],
  "Somethingelses": [
  ]
}

По сути, нужно сгруппировать все полезные нагрузки в массивы по их типу, сгруппированному по user_id

Я начал с JSONB_BUILD_OBJECT, собрав один из объектов object_types, сгруппированных в массив, но затем получил тупик.

Пытаюсь ли я достичь невозможного в сыром PSQL? Я действительно озадачен и продолжаю сталкиваться с ошибками, например, если X нужно включить в предложение GROUP BY и т. Д. c ...

Я могу сгруппировать один из типов object_types в массив, сгруппированный по user_id, но могу ' Кажется, я делаю все 3

Мое другое мнение состояло в том, чтобы иметь 3 подзапроса, но я тоже не уверен, как это сделать.

1 Ответ

1 голос
/ 02 февраля 2020

Вам нужны две агрегации, одна в группах по user_id, object_type, а другая только по user_id:

select 
    jsonb_build_object('user_id', user_id) 
    || jsonb_object_agg(object_type, payload) as result
from (
    select user_id, object_type, jsonb_agg(payload) as payload
    from my_table
    group by user_id, object_type
    ) s
group by user_id

Db <> Fiddle.

...