如何使用jsonb_build_object使用聚合函数和动态键值创建嵌套JSON返回

时间:2018-10-24 20:36:57

标签: sql json postgresql

这是表格的示例。

+---------------------+------------------+------------------+
|    country_code     |      region      |   num_launches   |
+---------------------+------------------+------------------+
|        'CA'         |     'Ontario'    |         5        |
+---------------------+------------------+------------------+
|        'CA'         |     'Quebec'     |         9        |
+---------------------+------------------+------------------+
|        'DE'         |     'Bavaria'    |         15       |
+---------------------+------------------+------------------+
|        'DE'         |    'Saarland'    |         12       |
+---------------------+------------------+------------------+
|        'DE'         |     'Berlin'     |         23       |
+---------------------+------------------+------------------+
|        'JP'         |     'Tokyo'      |         19       |
+---------------------+------------------+------------------+

我能够编写一个查询,该查询返回所有country_code嵌套在其中的每个regions,但是我无法准确获得所需的内容。

我想要的回报看起来像

[
  { 'CA': [
      { 'Ontario': 5 },
      { 'Quebec': 9 }
    ]
  },
  { 'DE': [
      { 'Bavaria': 15 },
      { 'Saarland': 12 },
      { 'Berlin': 23 }
    ]
  },
  { 'JP': [
      { 'Tokyo': 19 }
    ]
  }
]

如果num_launches不可用怎么计算?

+---------------------+------------------+
|    country_code     |      region      |
+---------------------+------------------+
|        'CA'         |     'Ontario'    |
+---------------------+------------------+
|        'CA'         |     'Ontario'    |
+---------------------+------------------+
|        'CA'         |     'Ontario'    |
+---------------------+------------------+
|        'CA'         |     'Quebec'     |
+---------------------+------------------+
|        'CA'         |     'Quebec'     |
+---------------------+------------------+
|        'DE'         |     'Bavaria'    |
+---------------------+------------------+
|        'DE'         |     'Bavaria'    |
+---------------------+------------------+
|        'DE'         |     'Bavaria'    |
+---------------------+------------------+
|        'DE'         |     'Bavaria'    |
+---------------------+------------------+
|        'DE'         |    'Saarland'    |
+---------------------+------------------+
|        'DE'         |     'Berlin'     |
+---------------------+------------------+
|        'DE'         |     'Berlin'     |
+---------------------+------------------+
|        'JP'         |     'Tokyo'      |
+---------------------+------------------+

预期收益

[
  { 'CA': [
      { 'Ontario': 3 },
      { 'Quebec': 2 }
    ]
  },
  { 'DE': [
      { 'Bavaria': 4 },
      { 'Saarland': 1 },
      { 'Berlin': 2 }
    ]
  },
  { 'JP': [
      { 'Tokyo': 1 }
    ]
  }
]

谢谢

1 个答案:

答案 0 :(得分:1)

您可以尝试在子查询中将json_aggjson_build_object函数一起使用以获取数组,然后在主查询中再次进行操作。

模式(PostgreSQL v9.6)

CREATE TABLE T(
   country_code varchar(50),
   region  varchar(50),
  num_launches int
);


insert into t values ('CA','Ontario',5);      
insert into t values ('CA','Quebec',9);       
insert into t values ('DE','Bavaria',15);     
insert into t values ('DE','Saarland',12);    
insert into t values ('DE','Berlin',23);      
insert into t values ('JP','Tokyo',19);       

查询#1

select json_agg(json_build_object(country_code,arr)) results
from (
  SELECT country_code,
         json_agg(json_build_object(region,num_launches)) arr 
  FROM T
  group by country_code
) t1;

结果

[{"CA":[{"Ontario":5},{"Quebec":9}]},{"DE":[{"Bavaria":15},{"Saarland":12},{"Berlin":23}]},{"JP":[{"Tokyo":19}]}] 

View on DB Fiddle