【问题标题】:Grouping json object in postgres在 postgres 中对 json 对象进行分组
【发布时间】:2019-10-31 15:43:59
【问题描述】:

我正在使用 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*****]}}

【问题讨论】:

  • 您想要的结果不是有效的 JSON。

标签: json postgresql postgresql-9.4


【解决方案1】:

有两个聚合函数可以做你想做的事情,除了存储数字而不是数组,如果它只有一个元素。

首先,您需要将数字聚合到: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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-26
    • 1970-01-01
    • 1970-01-01
    • 2018-03-19
    • 1970-01-01
    • 1970-01-01
    • 2020-09-20
    • 2021-12-22
    相关资源
    最近更新 更多