Processing Array_Agg Data in JSON Format in PostgreSQL

Avatar

By squashlabs, Last Updated: October 30, 2023

Processing Array_Agg Data in JSON Format in PostgreSQL

Aggregating JSON Data in PostgreSQL

JSON (JavaScript Object Notation) is a popular data format used for storing and exchanging data between a server and a client application. It provides a simple and lightweight way to represent structured data in a human-readable format. PostgreSQL, a useful open-source relational database management system, provides support for handling JSON data natively.

When working with JSON data in PostgreSQL, you may encounter scenarios where you need to aggregate JSON objects or arrays. The array_agg function in PostgreSQL allows you to aggregate values from multiple rows into an array. However, when dealing with JSON data, you may need to perform additional processing to extract and aggregate specific values.

In this article, we will explore various techniques and functions in PostgreSQL to process and aggregate JSON data using the array_agg function.

Related Article: Updating JSONB Columns in PostgreSQL

Using json_agg to Aggregate JSON Data in PostgreSQL

The json_agg function in PostgreSQL is used to aggregate values into a JSON array. It takes an input expression and returns a JSON array where each element is the result of evaluating the input expression.

Let’s consider an example where we have a table called employees with the following structure:

CREATE TABLE employees (
    id serial PRIMARY KEY,
    name varchar(100),
    department varchar(100),
    salary numeric
);

Suppose we have the following data in the employees table:

| id | name     | department | salary |
|----|----------|------------|--------|
| 1  | John Doe | Sales      | 5000   |
| 2  | Jane Doe | Marketing  | 6000   |
| 3  | Bob Smith| Sales      | 5500   |

If we want to aggregate the names of all employees into a JSON array, we can use the json_agg function as follows:

SELECT json_agg(name) FROM employees;

The result of the above query would be:

["John Doe", "Jane Doe", "Bob Smith"]

Using jsonb_agg to Aggregate JSON Data in PostgreSQL

Similar to json_agg, PostgreSQL also provides the jsonb_agg function to aggregate values into a JSONB array. The main difference between json_agg and jsonb_agg is that json_agg returns a JSON array, while jsonb_agg returns a JSONB array.

JSONB is a binary representation of JSON data that provides improved performance and storage efficiency compared to the traditional JSON data type.

The usage of jsonb_agg is similar to json_agg. Let’s consider the same example as before:

SELECT jsonb_agg(name) FROM employees;

The result of the above query would be the same as before:

["John Doe", "Jane Doe", "Bob Smith"]

Converting Array to JSON in PostgreSQL

In addition to aggregating JSON data, PostgreSQL also provides functions to convert arrays to JSON format. This can be useful when you have an array of values and want to represent it as a JSON array.

Using array_to_json to Convert Array to JSON in PostgreSQL

The array_to_json function in PostgreSQL is used to convert an array to a JSON array. It takes an input array and returns a JSON array where each element is the result of converting the corresponding element of the input array to JSON format.

Let’s consider an example where we have an array of colors:

SELECT array_to_json(ARRAY['red', 'green', 'blue']);

The result of the above query would be:

["red", "green", "blue"]

Using json_build_array to Build JSON Array in PostgreSQL

Another way to convert an array to JSON format in PostgreSQL is to use the json_build_array function. This function takes multiple arguments and builds a JSON array from them.

Let’s consider the same example as before:

SELECT json_build_array('red', 'green', 'blue');

The result of the above query would be the same as before:

["red", "green", "blue"]

Related Article: How to Export a PostgreSQL Query to CSV

Aggregating JSON Objects with json_object_agg in PostgreSQL

In addition to aggregating JSON arrays, PostgreSQL also provides the json_object_agg function to aggregate JSON objects. This function takes two arguments: a key expression and a value expression. It aggregates the key-value pairs into a JSON object.

Let’s consider an example where we have a table called employees with the following structure:

CREATE TABLE employees (
    id serial PRIMARY KEY,
    name varchar(100),
    department varchar(100),
    salary numeric
);

Suppose we have the following data in the employees table:

| id | name     | department | salary |
|----|----------|------------|--------|
| 1  | John Doe | Sales      | 5000   |
| 2  | Jane Doe | Marketing  | 6000   |
| 3  | Bob Smith| Sales      | 5500   |

If we want to aggregate the names and salaries of all employees into a JSON object, with the names as keys and salaries as values, we can use the json_object_agg function as follows:

SELECT json_object_agg(name, salary) FROM employees;

The result of the above query would be:

{
    "John Doe": 5000,
    "Jane Doe": 6000,
    "Bob Smith": 5500
}

Extracting Specific Values from JSON with json_extract_path in PostgreSQL

When working with JSON data in PostgreSQL, you may need to extract specific values from a JSON document. The json_extract_path function in PostgreSQL allows you to extract the value of a specific key or keys from a JSON document.

Let’s consider an example where we have a table called products with a column named data of type JSONB. The data column contains JSON data representing product information.

CREATE TABLE products (
    id serial PRIMARY KEY,
    name varchar(100),
    data jsonb
);

Suppose we have the following data in the products table:

| id | name     | data                                                                                                                                                                                                                                          |
|----|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1  | Product1 | {"name": "Product 1", "price": 100, "category": "Electronics"}                                                                                                                                                                               |
| 2  | Product2 | {"name": "Product 2", "price": 200, "category": "Appliances"}                                                                                                                                                                                |
| 3  | Product3 | {"name": "Product 3", "price": 300, "category": "Electronics", "details": {"weight": "1kg", "dimensions": {"length": 10, "width": 5, "height": 3}}}                                                                                         |

If we want to extract the price of each product, we can use the json_extract_path function as follows:

SELECT json_extract_path(data, 'price') FROM products;

The result of the above query would be:

100
200
300

Unnesting JSON Arrays with json_array_elements in PostgreSQL

When working with JSON arrays in PostgreSQL, you may need to unnest the array and return each element as a separate row. The json_array_elements function in PostgreSQL allows you to unnest a JSON array and return each element as a separate row.

Let’s consider an example where we have a table called employees with a column named data of type JSONB. The data column contains JSON data representing employee information, including a JSON array of skills.

CREATE TABLE employees (
    id serial PRIMARY KEY,
    name varchar(100),
    data jsonb
);

Suppose we have the following data in the employees table:

| id | name     | data                                                                                                                                                                                                                                          |
|----|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1  | John Doe | {"name": "John Doe", "skills": ["Java", "Python", "SQL"]}                                                                                                                                                                               |
| 2  | Jane Doe | {"name": "Jane Doe", "skills": ["JavaScript", "HTML", "CSS"]}                                                                                                                                                                                |
| 3  | Bob Smith | {"name": "Bob Smith", "skills": ["C++", "C#", "JavaScript"]}                                                                                                                                                                               |

If we want to unnest the skills of each employee and return each skill as a separate row, we can use the json_array_elements function as follows:

SELECT json_array_elements(data->'skills') FROM employees;

The result of the above query would be:

"Java"
"Python"
"SQL"
"JavaScript"
"HTML"
"CSS"
"C++"
"C#"
"JavaScript"

Unnesting JSONB Arrays with jsonb_array_elements in PostgreSQL

Similar to json_array_elements, PostgreSQL also provides the jsonb_array_elements function to unnest JSONB arrays. The usage of jsonb_array_elements is similar to json_array_elements.

Let’s consider the same example as before:

SELECT jsonb_array_elements(data->'skills') FROM employees;

The result of the above query would be the same as before:

"Java"
"Python"
"SQL"
"JavaScript"
"HTML"
"CSS"
"C++"
"C#"
"JavaScript"

Iterating over JSON Key-Value Pairs with json_each in PostgreSQL

In addition to unnesting JSON arrays, PostgreSQL also provides functions to iterate over JSON objects and extract key-value pairs. The json_each function in PostgreSQL allows you to iterate over the top-level key-value pairs of a JSON object and return each pair as a separate row.

Let’s consider an example where we have a table called employees with a column named data of type JSONB. The data column contains JSON data representing employee information.

CREATE TABLE employees (
    id serial PRIMARY KEY,
    name varchar(100),
    data jsonb
);

Suppose we have the following data in the employees table:

| id | name     | data                                                                                                                                                                                                                                          |
|----|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1  | John Doe | {"name": "John Doe", "age": 30, "department": "Sales"}                                                                                                                                                                               |
| 2  | Jane Doe | {"name": "Jane Doe", "age": 25, "department": "Marketing"}                                                                                                                                                                                |
| 3  | Bob Smith | {"name": "Bob Smith", "age": 35, "department": "Sales"}                                                                                                                                                                               |

If we want to iterate over the key-value pairs of the data column and return each pair as a separate row, we can use the json_each function as follows:

SELECT * FROM json_each(data) FROM employees;

The result of the above query would be:

name     | "John Doe"
age      | 30
department | "Sales"
name     | "Jane Doe"
age      | 25
department | "Marketing"
name     | "Bob Smith"
age      | 35
department | "Sales"

Iterating over JSONB Key-Value Pairs with jsonb_each in PostgreSQL

Similar to json_each, PostgreSQL also provides the jsonb_each function to iterate over JSONB objects. The usage of jsonb_each is similar to json_each.

Let’s consider the same example as before:

SELECT * FROM jsonb_each(data) FROM employees;

The result of the above query would be the same as before:

name     | "John Doe"
age      | 30
department | "Sales"
name     | "Jane Doe"
age      | 25
department | "Marketing"
name     | "Bob Smith"
age      | 35
department | "Sales"

Getting the Length of a JSONB Array in PostgreSQL

When working with JSONB arrays in PostgreSQL, you may need to determine the length of an array. The jsonb_array_length function in PostgreSQL allows you to get the length of a JSONB array.

Let’s consider an example where we have a table called employees with a column named data of type JSONB. The data column contains JSON data representing employee information, including a JSONB array of skills.

CREATE TABLE employees (
    id serial PRIMARY KEY,
    name varchar(100),
    data jsonb
);

Suppose we have the following data in the employees table:

| id | name     | data                                                                                                                                                                                                                                          |
|----|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1  | John Doe | {"name": "John Doe", "skills": ["Java", "Python", "SQL"]}                                                                                                                                                                               |
| 2  | Jane Doe | {"name": "Jane Doe", "skills": ["JavaScript", "HTML", "CSS"]}                                                                                                                                                                                |
| 3  | Bob Smith | {"name": "Bob Smith", "skills": ["C++", "C#", "JavaScript"]}                                                                                                                                                                               |

If we want to get the length of the skills array for each employee, we can use the jsonb_array_length function as follows:

SELECT jsonb_array_length(data->'skills') FROM employees;

The result of the above query would be:

3
3
3

Additional Resources

Using jsonb_agg to aggregate JSON arrays in PostgreSQL
Querying JSON array elements using jsonb_path_query_array in PostgreSQL