Aggregate multiple rows into a single JSON array (or object), collapsing a one-to-many relationship into a nested JSON structure within a query.
PostgreSQL aggregate function that collects rows into a JSON array, the inverse of json_each. Combines with ORDER BY within the aggregate to control array element order. The foundation of SQL-to-JSON transformations.
| Database System | Support Status | Since Version | Notes |
|---|---|---|---|
| MySQL | ✓ Supported | 5.7.22 | JSON_ARRAYAGG(expr) aggregates values into a JSON array. JSON_OBJECTAGG(key_expr, value_expr) aggregates key-value pairs into a JSON object. Both added in 5.7.22. No ORDER BY inside the aggregate — sort the outer query or use a subquery. NULL values in the expression are included as JSON null. |
| PostgreSQL | ✓ Supported | 9.3 | json_agg(expr) aggregates into a json array (since 9.3); jsonb_agg(expr) returns jsonb (since 9.4). json_object_agg(key, value) / jsonb_object_agg(key, value) aggregate into a JSON object. ORDER BY is supported inside the aggregate. NULL values are included as JSON null. Use FILTER (WHERE ...) to exclude rows. |
| SQL Server | ✗ Not Supported | — | No JSON_ARRAYAGG or json_agg. Use FOR JSON PATH / FOR JSON AUTO on a subquery to produce a JSON array. STRING_AGG can be combined with JSON_OBJECT (SQL Server 2022+) for simple cases. The result of FOR JSON is NVARCHAR, not a typed JSON column. |
| Oracle | ✓ Supported | 18c | JSON_ARRAYAGG(expr) and JSON_OBJECTAGG(key VALUE value) added in Oracle 18c. In Oracle 12c, workarounds include LISTAGG combined with manual JSON construction, or using JSON_ARRAY with a subquery. ORDER BY and ON NULL clauses supported inside JSON_ARRAYAGG. |
| SQLite | ✓ Supported | 3.9.0 | json_group_array(expr) aggregates values into a JSON array. json_group_object(name, value) aggregates into a JSON object. Both available since 3.9.0 when the JSON1 extension was added. In most SQLite distributions the JSON1 extension is compiled in by default. |
Function naming is completely non-standard across engines: json_agg (PostgreSQL), JSON_ARRAYAGG (MySQL/Oracle 18c), json_group_array (SQLite), and FOR JSON PATH (SQL Server). SQL Server is the only engine with no native aggregate function — it requires a subquery with FOR JSON. PostgreSQL is the only engine supporting ORDER BY inside the aggregate directly and offers FILTER (WHERE ...) for conditional aggregation. Oracle added JSON_ARRAYAGG in 18c; Oracle 12c users need a LISTAGG workaround.
JSON_ARRAYAGG(expr) aggregates values into a JSON array. JSON_OBJECTAGG(key_expr, value_expr) aggregates key-value pairs into a JSON object. Both added in 5.7.22. No ORDER BY inside the aggregate — sort the outer query or use a subquery. NULL values in the expression are included as JSON null.
json_agg(expr) aggregates into a json array (since 9.3); jsonb_agg(expr) returns jsonb (since 9.4). json_object_agg(key, value) / jsonb_object_agg(key, value) aggregate into a JSON object. ORDER BY is supported inside the aggregate. NULL values are included as JSON null. Use FILTER (WHERE ...) to exclude rows.
No JSON_ARRAYAGG or json_agg. Use FOR JSON PATH / FOR JSON AUTO on a subquery to produce a JSON array. STRING_AGG can be combined with JSON_OBJECT (SQL Server 2022+) for simple cases. The result of FOR JSON is NVARCHAR, not a typed JSON column.
JSON_ARRAYAGG(expr) and JSON_OBJECTAGG(key VALUE value) added in Oracle 18c. In Oracle 12c, workarounds include LISTAGG combined with manual JSON construction, or using JSON_ARRAY with a subquery. ORDER BY and ON NULL clauses supported inside JSON_ARRAYAGG.
json_group_array(expr) aggregates values into a JSON array. json_group_object(name, value) aggregates into a JSON object. Both available since 3.9.0 when the JSON1 extension was added. In most SQLite distributions the JSON1 extension is compiled in by default.