Question

I am still pretty new to PostgreSQL and I have trouble with aggregating a few rows and columns which I want to convert to valid JSON.

I have a Table like this:

 uid |         name        | count 
-----+--------------------+-------
  15 | latergram          |     1
  15 | wales              |     1

I want to concat the columns tag and count to something like '"name": count'. Afterwards I want to merge the rows with the same uid into one JSON Object. The final result should be something like this:

 uid |          json_agg          
-----+----------------------------
  15 | ["latergram":1, "wales":1]

But best i can manage is this, which is not a valid JSON:

 uid |          json_agg          
-----+----------------------------
  15 | ["latergram:1", "wales:1"]

This is the Query i used:

SELECT foo.uid, json_agg(foo.tag) 
from (
    SELECT uid, (concat(tag || ':' || count)) as tag from test 
) as foo 
group by foo.uid

But isn't there a better and especially correct way to achieve that via Postgres? Help will be much appreciated!

Was it helpful?

Solution 2

Hope this helps you:

with cte as(
   SELECT id, string_agg('"' || tag || '":' || count, ',') AS tag
   FROM Table1
   GROUP BY id
)
SELECT c.id, ('[' || c.tag || ']') FROM cte AS c

Answer is of the form :

   uid |          json_agg          
    -----+----------------------------
    15 | ["latergram":1, "wales":1]

DEMO

OTHER TIPS

Use the to_json() function on yout column name to produce valid JSON.
You don't need a subquery or CTE for this:

SELECT uid, '[' || string_agg(to_json(name) || ':' || ct, ',') || ']' AS tags
FROM   test
GROUP  BY 1;

Using column name ct instead of count which is a reserved word in standard SQL.

SQL FIiddle.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top