Reputation: 45
I have a table called "apples" that looks like this:
| not_a_pk | data (jsonb) |
|----------|-----------------------------------------------------------------------------------------------------------------------|
| 1 | [{"key":"color", "value":"red", "notes":"good apple"}, {"key":"size", "value":"large", "notes":"pretty large apple"}] |
| 2 | [{"key":"color", "value":"green", "notes":"too green"}, {"key":"size", "value":"small", "notes":"could be bigger"}] |
| 2 | [{"key":"color", "value":"purple", "notes":"weird"}, {"key":"size", "value":"miniscule", "notes":"actually a grape"}] |
I'd like to extract part of the object with the keys "key" and "value", as well as group by not_a_pk so that it looks like this:
| not_a_pk | data |
|----------|---------------------------------------------------------------------------------------------------------------------------------------------|
| 1 | [{"key":"color", "value":"red"}, {"key":"size", "value":"large"}] |
| 2 | [{"key":"color", "value":"green"}, {"key":"size", "value":"small"}, {"key":"color", "value":"purple"}, {"key":"size", "value":"miniscule"}] |
I've been able to just grab all the values under a single key, like {"key": ["color", "size", "color", "size"]} but I can't figure out how to keep them as regular objects with separate keys.
Upvotes: 0
Views: 458
Reputation:
You need to unnest the array elements, construct the new JSON objects and then aggregate back into an array:
select a.not_a_pk,
jsonb_agg(jsonb_build_object('key', x.item -> 'key', 'value', x.item -> 'value')) as data
from apples a
cross join jsonb_array_elements(a.data) as x(item)
group by a.not_a_pk
order by a.not_a_pk;
Upvotes: 3