PostgreSQL jsonb_object_agg() Function
The PostgreSQL jsonb_object_agg()
function is an aggregate function that returns a JSON object consisting of a set of key-value pairs.
jsonb_object_agg()
Syntax
Here is the syntax of the PostgreSQL jsonb_object_agg()
function:
jsonb_object_agg(key_expr, value_expr) -> JSON
Typically, we use the jsonb_object_agg()
function like:
SELECT jsonb_object_agg(expr), ...
FROM table_name
[WHERE ...]
[GROUP BY group_expr1, group_expr2, ...];
Parameters
key_expr
-
Required. A column name or expression used to generate the key of the key-value pair in the JSON object.
value_expr
-
Required. A column name or expression used to generate the value of a key-value pair in a JSON object.
Return value
The PostgreSQL jsonb_object_agg()
function returns an object that contains key-value pairs consisting of the specified column or expression in a group, where the key_expr
is used as the key in the key-value pair, and the value_expr
converted to a JSON value using the to_json()
function is used as the value in the key-value pair.
jsonb_object_agg()
Examples
To demonstrate usages of the PostgreSQL jsonb_object_agg()
function, we simulate a temporary table using the following statement with UNION
and SELECT
:
SELECT 'Tim' name, 'Math' subject, 'A' grade
UNION
SELECT 'Tim' name, 'English' subject, 'B' grade
UNION
SELECT 'Tom' name, 'Math' subject, 'B' grade
UNION
SELECT 'Tom' name, 'English' subject, 'A' grade;
name | subject | grade
------+---------+-------
Tom | English | A
Tom | Math | B
Tim | English | B
Tim | Math | A
(4 rows)
Here, we have some rows for user grades. The name
column is the name of the user, the subject
column is the name of the subject, and the grade
column is the grade of a subject.
Suppose, if you want to put all grades for each user (users with the same name are treated as one user) in a single JSON object, you can use the GROUP BY
clause to group all rows by name
and use the jsonb_object_agg()
function to construct a JSON object with the subject as key and the grade as value in each group. The following statement fulfills this requirement:
SELECT
t.name,
jsonb_object_agg(t.subject, t.grade) grades
FROM (
SELECT 'Tim' name, 'Math' subject, 'A' grade
UNION
SELECT 'Tim' name, 'English' subject, 'B' grade
UNION
SELECT 'Tom' name, 'Math' subject, 'B' grade
UNION
SELECT 'Tom' name, 'English' subject, 'A' grade
) t
GROUP BY t.name;
name | grades
------+-------------------------------
Tim | {"Math": "A", "English": "B"}
Tom | {"Math": "B", "English": "A"}
(2 rows)
here,
- For Tim, his grades are aggregated into a JSON object
{ "English" : "B", "Math" : "A" }
. - For Tom, his grades are aggregated into a JSON object
{ "English" : "A", "Math" : "B" }
.