简体   繁体   English

Postgres 中的嵌套 JSON 聚合

[英]Nested JSON aggregation in Postgres

I have a need to run a query over a Postgres database and aggregate it and export it as a json object using native Postgres tooling.我需要在 Postgres 数据库上运行查询并将其聚合并使用本机 Postgres 工具将其导出为 json 对象。

I can't quite get the aggregation working correctly and I'm a bit stumped.我不能完全让聚合正常工作,我有点难住了。

Below is an example of some of the data下面是一些数据的例子

| 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 |
+-----------+---------------+-------------+-----------------------------------------------------------+---------+

I need to output a JSON object like this grouped by user_id我需要输出一个像这样按 user_id 分组的 JSON 对象

{
  "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": [
  ]
}

Essentially need to group al the payloads into arrays by their type grouped by the user_id基本上需要将所有有效负载按其类型分组到数组中,这些类型由 user_id 分组

I started with JSONB_BUILD_OBJECT getting one of the object_types grouped together into an array but then got stumped.我从 JSONB_BUILD_OBJECT 开始,将 object_types 组合成一个数组,但后来被难住了。

Am I trying to achieve the impossible in raw PSQL?我是否试图在原始 PSQL 中实现不可能的目标? I'm really stumped and I keep hitting errors like X needs to be included in the GROUP BY clause etc...我真的很难过,我一直遇到错误,比如 X 需要包含在 GROUP BY 子句中等等......

I can group one of the object_types into an array grouped by user_id but can't seem to do all 3我可以将 object_types 之一分组到按 user_id 分组的数组中,但似乎无法完成所有 3

My other thinking was to do have 3 subqueries but I'm not sure how to do that either.我的另一个想法是有 3 个子查询,但我也不知道该怎么做。

You need two aggregations, first one in groups by user_id, object_type and the other by user_id only:您需要两个聚合,第一个按user_id, object_type分组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. Db<>小提琴。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM