1

This is what and example of the table looks like.

+---------------------+------------------+------------------+
|    country_code     |      region      |   num_launches   |
+---------------------+------------------+------------------+
|        'CA'         |     'Ontario'    |         5        |
+---------------------+------------------+------------------+
|        'CA'         |     'Quebec'     |         9        |
+---------------------+------------------+------------------+
|        'DE'         |     'Bavaria'    |         15       |
+---------------------+------------------+------------------+
|        'DE'         |    'Saarland'    |         12       |
+---------------------+------------------+------------------+
|        'DE'         |     'Berlin'     |         23       |
+---------------------+------------------+------------------+
|        'JP'         |     'Tokyo'      |         19       |
+---------------------+------------------+------------------+

I am able to write a query that returns each country_code with all regions nested within, but I am unable to get exactly what I am looking for.

My intended return looks like.

[
  { 'CA': [
      { 'Ontario': 5 },
      { 'Quebec': 9 }
    ]
  },
  { 'DE': [
      { 'Bavaria': 15 },
      { 'Saarland': 12 },
      { 'Berlin': 23 }
    ]
  },
  { 'JP': [
      { 'Tokyo': 19 }
    ]
  }
]

How could this be calculated if the num_launches was not available?

+---------------------+------------------+
|    country_code     |      region      |
+---------------------+------------------+
|        'CA'         |     'Ontario'    |
+---------------------+------------------+
|        'CA'         |     'Ontario'    |
+---------------------+------------------+
|        'CA'         |     'Ontario'    |
+---------------------+------------------+
|        'CA'         |     'Quebec'     |
+---------------------+------------------+
|        'CA'         |     'Quebec'     |
+---------------------+------------------+
|        'DE'         |     'Bavaria'    |
+---------------------+------------------+
|        'DE'         |     'Bavaria'    |
+---------------------+------------------+
|        'DE'         |     'Bavaria'    |
+---------------------+------------------+
|        'DE'         |     'Bavaria'    |
+---------------------+------------------+
|        'DE'         |    'Saarland'    |
+---------------------+------------------+
|        'DE'         |     'Berlin'     |
+---------------------+------------------+
|        'DE'         |     'Berlin'     |
+---------------------+------------------+
|        'JP'         |     'Tokyo'      |
+---------------------+------------------+

Expected Return

[
  { 'CA': [
      { 'Ontario': 3 },
      { 'Quebec': 2 }
    ]
  },
  { 'DE': [
      { 'Bavaria': 4 },
      { 'Saarland': 1 },
      { 'Berlin': 2 }
    ]
  },
  { 'JP': [
      { 'Tokyo': 1 }
    ]
  }
]

Thanks

1 Answer 1

2

You can try to use json_agg with json_build_object function in a subquery to get the array then do it again in the main query.

Schema (PostgreSQL v9.6)

CREATE TABLE T(
   country_code varchar(50),
   region  varchar(50),
  num_launches int
);


insert into t values ('CA','Ontario',5);      
insert into t values ('CA','Quebec',9);       
insert into t values ('DE','Bavaria',15);     
insert into t values ('DE','Saarland',12);    
insert into t values ('DE','Berlin',23);      
insert into t values ('JP','Tokyo',19);       

Query #1

select json_agg(json_build_object(country_code,arr)) results
from (
  SELECT country_code,
         json_agg(json_build_object(region,num_launches)) arr 
  FROM T
  group by country_code
) t1;

results

[{"CA":[{"Ontario":5},{"Quebec":9}]},{"DE":[{"Bavaria":15},{"Saarland":12},{"Berlin":23}]},{"JP":[{"Tokyo":19}]}] 

View on DB Fiddle

Sign up to request clarification or add additional context in comments.

1 Comment

How would I adjust the query if the num_launches column were not immediately available. I put an example in the question body.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.