Version: PostgreSQL 11.4 (Ubuntu 11.4-1.pgdg19.04+1).

Question: Is possible export to json file? Something like csv export.

TO stdout DELIMITER '"' csv;


Update: Or can I add escape character \ just for fields param_name and value for this?

string_agg(distinct '{name:"' || param_name || '",value:"' || value || '"}',',') as "params",

Result is:


I need this (use \ before " only for fields param_name and value:


Update2: Whole sql command added. How to implement function row_to_json? Just add row_to_json to every item in select I have? For example:

select row_to_json(string_agg(distinct '{name:"' || param_name || '",value:"' || value || '"}',',') as "params"),


Whole sql.

with recursive
cte as(
category_id::text category_ids
from s_category as c
where category_parent = 0
union all
concat(cte.category_name, ' > ', c.category_name),
concat(cte.category_ids, ':', c.category_id::text)
from s_category as c,cte
where cte.category_id = c.category_parent

select distinct
s_product.product_id as "itemID",
s_product.product_id as "itemGroupID",
product_shop_id as "productCode",
product_ean as "ean",
product_name as "title",
product_short_label as "description",
concat('https://eshop.unihobby.cz/',product_url,'/',s_product.product_id,'p/') as "link",
concat('https://eshop.unihobby.cz/bin/product/4/',filename) as "image",
price_tax as "price",
price_rec as "priceOriginal",
available_count as "available",
when available_count >= 5 then 'SKLADEM > 5 KS'
when available_count < 5 then 'SKLADEM < 5 KS'
when available_couNt = 0 then 'NENÍ SKLADEM'
end as "availability",
producer_name as "brand",
concat('Úvod > ',cte.category_name) as "category",
s_category.category_id as "categoryID",
cte.category_ids as "hierarchy",
string_agg(distinct '{name:"' || param_name || '",value:"' || value || '"}',',') as "params",
case when price_tax = price_rec then '' else 'Akce' end as "label"

left join s_cf_j_product_value on s_product.product_id = s_cf_j_product_value.product_id
left join s_product_image on s_product.product_id = s_product_image.product_id
left join s_pricelist_generated_lists on s_product.product_id = s_pricelist_generated_lists.product_id
left join s_producer on s_product.producer_id = s_producer.producer_id
left join s_category on s_product.category_id = s_category.category_id
left join cte on s_product.category_id = cte.category_id
left join s_cf_j_product_value as a on s_product.product_id = a.product_id
left join s_cf_value as v on a.value_id = v.value_id
left join s_cf_param as p on v.param_id = p.param_id

image_order = '0'
and s_category.category_name is not null
and product_active = 'y'
and s_pricelist_generated_lists.group_id = '10'
--and s_product.product_id = '133471'

group by

Is possible export to json file? Something like csv export.

Yes. Try this:

select row_to_json(tablename.*,true) from tablename;


copy (select row_to_json(tablename.*,true) from tablename) to stdout;

if you need copy.

See row_to_json along with other JSON functions in the documentation: JSON Functions and Operators.

I wouldn't recommend CSV on top of JSON because double quotes are special for both CSV and JSON, and they will be doubled for CSV, which makes the output less readable.

The same goes more or less for the text format of COPY. A plain SELECT without any additional quoting may be simpler.

Update: tablename can be a subquery. For the large subquery in the updated question, you may write

select row_to_json(v.*) FROM ( ...subquery here... ) AS v;

Alternatively, a temporary view may also be helpful to improve readibility or ease of use.

CREATE TEMPORARY VIEW tmpview AS ...subquery here...;

SELECT row_to_json(v.*,true) from tmpview;

The temporary view will be automatically removed at the end of the session.

| improve this answer | |
  • Thanks, but how can I implement this function? Is it simple? I tried, but false, see Update2 in my question. Thank you. – genderbee Aug 5 '19 at 12:51
  • @genderbee: please see the update. – Daniel Vérité Aug 5 '19 at 17:37
  • Thanks, seems this is working. :) – genderbee Aug 6 '19 at 7:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.