Implementando json_object_agg () no Postgres 9.3


9

Sinto que preciso da json_object_agg()função do Postgres 9.4, mas não poderei atualizar a partir da 9.3 no momento. Existe uma maneira de fazer o que eu quero na 9.3? Aqui está o meu cenário. Eu tenho uma tabela click_activityde dados que parece

user | offer | clicks
-----|-------|--------
fred |coupons| 3
fred |cars   | 1
john |coupons| 2

Mas quero transformar isso em: (agregar a atividade por usuário)

user | activity
-----|----------
fred | {"coupons": 3, "cars": 1}
john | {"coupons": 2}

Eu acho que a json_object_agg()função do Postgres 9.4 faria isso perfeitamente, tudo o que eu teria que chamar é

select user, json_object_agg(offer, clicks) from click_activity group by 1

Existe uma maneira de fazer isso na 9.3? Obrigado!


11
Pode ser relativamente fácil de extrair a função e envolvê-lo em uma extensão de C ...
Craig Ringer

Você pode usar o pl / v8?
Clément Prévost

Respostas:


9

Consegui emular o json_object_agg usando string_agg (disponível na 9.3).

Seu exemplo seria:

select user, ('{' || string_agg('"' || offer || '": ' || clicks, ',') || '}')::json as activity 
from click_activity 
group by user

Isso não executará escapes corretamente. Se os valores contiverem aspas ou outros caracteres com significados especiais em JSON, isso gerará um erro ou gerará um resultado incorreto.
precisa saber é o seguinte

Isso pode ser corrigido estar substituindo o manual citando com apenas uma to_jsonchamada: ('{' || string_agg(to_json(offer) || ': ' || to_json(clicks), ',') || '}')::json. As aspas duplas são adicionadas automaticamente ao redor do offervalor ao concatená-lo.
jpmc26

0

Use insteade de json_object_agg => json_agg

select user, json_agg((offer, clicks)) from click_activity group by 1

11
, Bem-vindo ao StackExchange. Por favor, adicione algumas notas relacionadas à consulta, para melhor compreensão.
Md Haidar Ali Khan
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.