Set names to attributes when creating JSON with row_to_json
select
c.id,
(select row_to_json(_) from (select c.first_name, c.last_name) as _) as first_last,
c.age
from
customers as c
will do what you want without any performance impact (and is not too verbose):
id | first_last | age
------+---------------------------------------------+---------
1 | {"fisrt_name": "John", "last_name": "Smit"} | 34
A common table expression allows you to specify aliases explicitly, not only for the CTE but for its columns.
WITH data(col1,col2,cola,colb) AS (
VALUES (1,2,'fred','bob')
)
SELECT row_to_json(data) FROM data;
This is different to @dezso's example in that it doesn't use col AS alias
for each col in a SELECT
list; it aliases the column names in the CTE table alias.
I've used a VALUES
expression as a subquery but you can use a SELECT
whatever you like; the point is that whatever column-aliases are provided or assumed in the subquery can be overridden in the CTE definition by specifying a column-name-list.
You can do the same thing in a subquery, again instead of using AS alias
:
SELECT row_to_json(data)
FROM (VALUES (1,2,'fred','bob')) data(col1,col2,cola,colb);
This doesn't work with a ROW
expression directly; you can only cast a ROW
to a concrete type, you cannot alias it.
regress=> SELECT ROW(1,2,'fred','bob') AS x(a,b,c,d);
ERROR: syntax error at or near "("
LINE 1: SELECT ROW(1,2,'fred','bob') AS x(a,b,c,d);
You can use json_build_object
.
SELECT
json_build_object('id', data.customer_id, 'first_name', data.first_name, 'last_name', data.last_name) as your_json
FROM data;