I would like to aggregate two columns into one \"array\" when grouping.
Assume a table like so:
friends_map:
=================================
user_i
You can concatenate the values together prior to feeding them into the array_agg()
function:
SELECT user_id, array_agg('[' || friend_id || ',' || confirmed || ']') as friends
FROM friends_map
WHERE user_id = 1
GROUP BY user_id
Demo: SQL Fiddle
In Postgres 9.5 you can obtain array of arrays of text:
SELECT user_id, array_agg(array[friend_id::text, confirmed::text])
FROM friend_map
WHERE user_id = 1
GROUP BY user_id;
user_id | array_agg
---------+--------------------------------
1 | {{2,true},{3,false},{4,false}}
(1 row)
or array of arrays of int:
SELECT user_id, array_agg(array[friend_id, confirmed::int])
FROM friend_map
WHERE user_id = 1
GROUP BY user_id;
user_id | array_agg
---------+---------------------
1 | {{2,1},{3,0},{4,0}}
(1 row)
You could avoid the ugliness of the multidimentional array and use some json which supports mixed datatypes:
SELECT user_id, json_agg(json_build_array(friend_id, confirmed)) AS friends
FROM friends_map
WHERE user_id = 1
GROUP BY user_id
Or use some key : value
pairs since json allows that, so your output will be more semantic if you like:
SELECT user_id, json_agg(json_build_object(
'friend_id', friend_id,
'confirmed', confirmed
)) AS friends
FROM friends_map
WHERE user_id = 1
GROUP BY user_id;
You can use: array[]
Just do that:
SELECT user_id, array[friend_id, confirmed]
FROM friend_map
WHERE user_id = 1
GROUP BY 1;
SELECT user_id, array_agg((friend_id, confirmed)) as friends
FROM friend_map
WHERE user_id = 1
GROUP BY user_id
user_id | array_agg
--------+--------------------------------
1 | {"(2,true)","(3,false)","(4,false)"}