Reputation: 10534
I have a postgresql table
alok=# select * from people;
name | country | city
---------+---------+---------
alok | india | delhi
ram | india | kolkata
shyam | india | kanpur
krishna | us | newyork
ajit | india | delhi
sami | india | delhi
mohamad | india | kolkata
(7 rows)
which can be produced by
create table people(name varchar, country varchar, city varchar);
insert into people values('alok', 'india', 'delhi');
insert into people values('ram', 'india', 'kolkata');
insert into people values('shyam', 'india', 'kanpur');
insert into people values('krishna', 'us', 'newyork');
insert into people values('ajit', 'india', 'delhi');
insert into people values('sami', 'india', 'delhi');
insert into people values('mohamad', 'india', 'kolkata');
I want to produce aggregated name on country and city like
country | name
---------+------------------------------------
india | {"delhi":["alok", "ajit", "sami"], "kolkata":["ram", "mohamad"], "kanpur":["shyam"]}
us | {"newyork":["krishna"]}
Upvotes: 2
Views: 289
Reputation: 39
select
country, json_agg( json_build_object( 'city', city, 'name', name ) )
from (
select country, city, json_agg( name ) as name
from people
group by country, city
) a
group by a.country;
Upvotes: 0
Reputation: 23676
SELECT
country,
json_object_agg(city, agg_names)
FROM (
SELECT
country,
city,
json_agg(name) AS agg_names
FROM
people
GROUP BY country, city
) s
GROUP BY country
city
. To put the name
s into one JSON array you can use the aggregate function json_agg()
country
. To get the expected output you need to use the aggregate function json_object_agg()
which creates key/pair values from city
and name
arrayUpvotes: 3