Postgresql group by query 转换json格式

问题描述

我的表格数据如下;

_id product_id product_name sell_price 购买价格 国家
1 prd_1 产​​品一 15 12 美国
2 prd_1 产​​品一 16 13 加拿大
3 prd_2 产​​品二 7 5 中国
4 prd_2 产​​品二 12 10 日本

我想根据产品对其进行分组并将其转换为 json 格式。我想要的最终版本如下;

{ 
    "_id" : "prd_1","details" : [
        {
            "_id" : 1,"product_id" : "prd_1","product_name" : "product one","sell_price" : 15,"purchase_price" : 12,"country" : "usa"
        },{
            "_id" : 2,"sell_price" : 16,"purchase_price" : 13,"country" : "canada"
        },]
}
{ 
    "_id" : "prd_2","details" : [
        {
            "_id" : 3,"product_id" : "prd_2","product_name" : "product two","sell_price" : 7,"purchase_price" : 5,"country" : "china"
        },{
            "_id" : 4,"sell_price" : 10,"country" : "japan"
        },]
}

我创建了以下查询,但它没有给出我想要的结果。因为我只想一列所有 json 对象。我们如何创建我想要的查询?有可能吗?

select product_id,json_agg(obj) as details
  from (
    select product_id,json_build_object(
           '_id',_id,'product_id',product_id,'product_name',product_name,'sell_price',sell_price,'purchase_price',purchase_price,'country',country
         ) as obj
  from products p) tmp
group by product_id;

解决方法

你很接近。只需要将整个内容包装在另一个 json_agg() 中即可将其合并为一行:

edb=# select jsonb_pretty(json_agg(tb)::jsonb) from (
  select _id,json_agg(obj) as details
  from (
    select product_id as _id,json_build_object(
           '_id',_id,'product_id',product_id,'product_name',product_name,'sell_price',sell_price,'purchase_price',purchase_price,'country',country
         ) as obj
    from products p) tmp
    group by _id) as tb;
                  jsonb_pretty                  
------------------------------------------------
 [                                             +
     {                                         +
         "_id": "prd_2",+
         "details": [                          +
             {                                 +
                 "_id": 3,+
                 "country": "china",+
                 "product_id": "prd_2",+
                 "sell_price": 7,+
                 "product_name": "product two",+
                 "purchase_price": 5           +
             },+
             {                                 +
                 "_id": 4,+
                 "country": "japan",+
                 "sell_price": 12,+
                 "purchase_price": 10          +
             }                                 +
         ]                                     +
     },+
     {                                         +
         "_id": "prd_1",+
         "details": [                          +
             {                                 +
                 "_id": 1,+
                 "country": "usa",+
                 "product_id": "prd_1",+
                 "sell_price": 15,+
                 "product_name": "product one",+
                 "purchase_price": 12          +
             },+
             {                                 +
                 "_id": 2,+
                 "country": "canada",+
                 "sell_price": 16,+
                 "purchase_price": 13          +
             }                                 +
         ]                                     +
     }                                         +
 ]
(1 row)