Группировка объектов json в postgres - PullRequest
1 голос
/ 18 июня 2019

Я вставляю в postgres с помощью select.В основном преобразование в тип 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 голосов
/ 18 июня 2019

Существуют две функции агрегирования, которые должны выполнять то, что вы хотите, за исключением сохранения чисел не в виде массива, если в нем будет только один элемент.

Сначала вам нужно агрегировать числа с: 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)
...