如何从 json.agg() 函数返回不同的值

mik*_*ssy 3 postgresql json

我有以下查询

select json_agg(t) from (
select  json_build_object(
'field_1',a.field_1,
'field_2',a.field_2,
'field_4',json_agg(json_build_object('id',g.id,'data',g.fullname)),
'field_9',json_agg(json_build_object('id',i.optionid,'data',i.option))
 ) as data

from schema_1.tbl_342 a
left join schema_1.tbl_342_to_tbl_329_field_10 b on a.id=b.tbl_342_id
left join schema_1.tbl_329_customid c on b.tbl_329_id=c.id
left join schema_1.tbl_329_field_23_join d on c.id=d.id
left join schema_1.tbl_329_field_23 e on d.optionid = e.optionid
left join schema_1.tbl_342_to_tbl_312_field_4 f on a.id=f.tbl_342_id
left join schema_1.tbl_312_customid g on f.tbl_312_id = g.id
left join schema_1.tbl_342_field_9_join h on h.id=a.id
left join schema_1.tbl_342_field_9 i on i.optionid=h.optionid   
group by a.field_1,a.field_2
) t
Run Code Online (Sandbox Code Playgroud)

这会产生以下JSON格式

   [
  {
  "data":{
     "field_1":"John",
     "field_2":null,
     "field_4":[
        {
           "id":null,
           "data":null
        }
     ],
     "field_9":[
        {
           "id":2,
           "data":"Green"
        }
     ]
  }
 },
 {
  "data":{
     "field_1":"Jackson",
     "field_2":null,
     "field_4":[
        {
           "id":2,
           "data":"Marketing Manager M1004"
        },
        {
           "id":4,
           "data":"Senior Javascript Engineer"
        },
        {
           "id":5,
           "data":"Recruiter"
        }
     ],
     "field_9":[
        {
           "id":3,
           "data":"Red"
        },
        {
           "id":3,
           "data":"Red"
        },
        {
           "id":3,
           "data":"Red"
        }
     ]
  }
 },
  {
    "data":{
     "field_1":"Jacob",
     "field_2":null,
     "field_4":[
        {
           "id":null,
           "data":null
        }
     ],
     "field_9":[
        {
           "id":null,
           "data":null
        }
     ]
  }
 },
 {
  "data":{
     "field_1":"Todd",
     "field_2":null,
     "field_4":[
        {
           "id":null,
           "data":null
        }
     ],
     "field_9":[
        {
           "id":4,
           "data":"Yellow"
        }
     ]
  }
 },
 {
  "data":{
     "field_1":"Billy",
     "field_2":null,
     "field_4":[
        {
           "id":5,
           "data":"Recruiter"
        }
     ],
     "field_9":[
        {
           "id":1,
           "data":"Blue"
        }
     ]
   }
 }
 ]
Run Code Online (Sandbox Code Playgroud)

在此示例中,我尝试修复两件事。

1.删​​除data节点元素。我想让对象从根开始,而不是从Data

2.通知在第二个节点。有field_43 个元素,但在 DB 中field_9只有一个值。red这里重复重复的值,必须与返回的记录数匹配field_4

我怎样才能从这个聚合中获得不同的值?我试过了

 'field_4',distinct json_agg(json_build_object('id',g.id,'data',g.fullname)),
Run Code Online (Sandbox Code Playgroud)

和其他类似的形式,但它不喜欢语法。仅供参考,我正在使用 PostgreSQL 11

Akh*_*hra 6

您的问题的答案和解决方案如下:

问题 1 - 您正在用来json_agg(t)生成最终JSON数据,该数据将选择所有列名称或别名作为键JSON并对其进行聚合。所以这里你应该使用array_to_json(array_agg(t.data)). array_agg将子查询的结果转换为数组,然后 array_to_json 将最终数组转换为JSON.

问题 2 - 你想要distinct json object内部数组。因此Distinct不能与json数据类型一起使用,因为没有equality operator可用的PostgreSQLforJSON类型。所以你应该使用JSONB.

考虑到问题中提到的查询工作正常,请尝试一下:

select array_to_json(array_agg(t.data)) from (
select  jsonb_build_object(
'field_1',a.field_1,
'field_2',a.field_2,
'field_4',jsonb_agg(distinct jsonb_build_object('id',g.id,'data',g.fullname)),
'field_9',jsonb_agg(distinct jsonb_build_object('id',i.optionid,'data',i.option))
 ) as data

from schema_1.tbl_342 a
left join schema_1.tbl_342_to_tbl_329_field_10 b on a.id=b.tbl_342_id
left join schema_1.tbl_329_customid c on b.tbl_329_id=c.id
left join schema_1.tbl_329_field_23_join d on c.id=d.id
left join schema_1.tbl_329_field_23 e on d.optionid = e.optionid
left join schema_1.tbl_342_to_tbl_312_field_4 f on a.id=f.tbl_342_id
left join schema_1.tbl_312_customid g on f.tbl_312_id = g.id
left join schema_1.tbl_342_field_9_join h on h.id=a.id
left join schema_1.tbl_342_field_9 i on i.optionid=h.optionid   
group by a.field_1,a.field_2
) t
Run Code Online (Sandbox Code Playgroud)