在PostgreSQL中对JSON对象进行分组

时间:2019-06-18 04:03:43

标签: json postgresql postgresql-9.4

我正在使用select插入postgres。基本上转换为json类型。

SELECT DISTINCT  ON (name, number)
  JSON_BUILD_OBJECT(name, JSON_BUILD_OBJECT(phone_number_of, number))
FROM table1 t1, tale2 t2, table3 t3
WHERE
  t1.customer_fk_id = t2.id
AND t1.id = t3.proposal_customer_id
ORDER BY name, number, priority DESC

我得到了输出:

{"ALIP KUMAR" : {"Mobile" : "8*******"}}
{"ALIP KUMAR" : {"Residence" : "9******"}}
{"Abdul Gaffar" : {"Office" : "9*******"}}
{"Abdul Khalique" : {"Mobile" : "98*****"}}
{"Abdul Khalique" : {"Mobile" : "97*****"}}

有没有办法对数据进行分组,所以一个名字有一个包含所有密钥的密钥,即手机,住所等。 如果要居住的人数有多个,则将其放在列表中。 输出应为

{"ALIP KUMAR" : {"Mobile" : "8*******"}
                 "Residence" : "9******"}}
{"Abdul Gaffar" : {"Office" : "9*******"}}
{"Abdul Khalique" : {"Mobile" : ["98*****", "97*****]}}

1 个答案:

答案 0 :(得分:0)

有两个聚合函数可以满足您的期望,但如果仅将一个元素存储为数组,则不存储数字。

首先,您需要将数字汇总到json_agg(number),并按name, phone_number_of分组

然后,如果您需要使用单个电话号码作为数字/字符串而不是数组,则使用json_array_length(json)检查长度,如果长度小于2,则使用json->>0抓取第一个元素并使用它数组。

一旦有了name, phone_number_of, number_array_or_value,然后将它们按name分组,并使用函数json_object_agg(key, value)

进行汇总

此处描述了这些聚合函数:https://www.postgresql.org/docs/9.4/functions-aggregate.html

示例:

select json_object_agg(name, phones)
  from (
        select name,
               json_object_agg(typ, case when json_array_length(numbers) < 2 then numbers->0 else numbers end) as phones
          from (
                select name, typ, json_agg(number) as numbers
                  from (
                        select 'name1' as name, 'work' as typ, '34636432' as number
                        union all
                        select 'name1' as name, 'mobile' as typ, '12453435' as number
                        union all
                        select 'name1' as name, 'mobile' as typ, '654745' as number
                        union all
                        select 'name2' as name, 'home' as typ, '8643534434' as number
                        union all
                        select 'name3' as name, 'work' as typ, '24778457' as number
                       ) AS sub1
                 group by name, typ
               ) AS sub2
         group by name
      ) as sub3
 group by name;

                             json_object_agg
--------------------------------------------------------------------------
 { "name2" : { "home" : "8643534434" } }
 { "name3" : { "work" : "24778457" } }
 { "name1" : { "work" : "34636432", "mobile" : ["12453435", "654745"] } }
(3 rows)