Postgres - 将两列聚合成一个项目
Postgres - aggregate two columns into one item
我想在分组时将两列合并为一列"array"。
假设 table 像这样:
friends_map:
=================================
user_id friend_id confirmed
=================================
1 2 true
1 3 false
2 1 true
2 3 true
1 4 false
我想从这个 table 中 select 并按 user_id 分组并得到 friend_id 并确认为以逗号分隔的串联值。
目前我有这个:
SELECT user_id, array_agg(friend_id) as friends, array_agg(confirmed) as confirmed
FROM friend_map
WHERE user_id = 1
GROUP BY user_id
这让我:
=================================
user_id friends confirmed
=================================
1 [2,3,4] [t, f, f]
如何获得:
=================================
user_id friends
=================================
1 [ [2,t], [3,f], [4,f] ]
您可以在将值输入 array_agg()
函数之前将它们连接在一起:
SELECT user_id, array_agg('[' || friend_id || ',' || confirmed || ']') as friends
FROM friends_map
WHERE user_id = 1
GROUP BY user_id
演示:SQL Fiddle
在 Postgres 9.5 你可以获得文本数组的数组:
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)
或 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)
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)"}
你可以避免多维数组的丑陋并使用一些支持混合数据类型的json:
SELECT user_id, json_agg(json_build_array(friend_id, confirmed)) AS friends
FROM friends_map
WHERE user_id = 1
GROUP BY user_id
或者使用一些 key : value
对,因为 json 允许这样做,所以你的输出会更 语义 如果你喜欢的话:
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;
您可以使用:array[]
就这样做:
SELECT user_id, array[friend_id, confirmed]
FROM friend_map
WHERE user_id = 1
GROUP BY 1;
我想在分组时将两列合并为一列"array"。
假设 table 像这样:
friends_map:
=================================
user_id friend_id confirmed
=================================
1 2 true
1 3 false
2 1 true
2 3 true
1 4 false
我想从这个 table 中 select 并按 user_id 分组并得到 friend_id 并确认为以逗号分隔的串联值。
目前我有这个:
SELECT user_id, array_agg(friend_id) as friends, array_agg(confirmed) as confirmed
FROM friend_map
WHERE user_id = 1
GROUP BY user_id
这让我:
=================================
user_id friends confirmed
=================================
1 [2,3,4] [t, f, f]
如何获得:
=================================
user_id friends
=================================
1 [ [2,t], [3,f], [4,f] ]
您可以在将值输入 array_agg()
函数之前将它们连接在一起:
SELECT user_id, array_agg('[' || friend_id || ',' || confirmed || ']') as friends
FROM friends_map
WHERE user_id = 1
GROUP BY user_id
演示:SQL Fiddle
在 Postgres 9.5 你可以获得文本数组的数组:
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)
或 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)
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)"}
你可以避免多维数组的丑陋并使用一些支持混合数据类型的json:
SELECT user_id, json_agg(json_build_array(friend_id, confirmed)) AS friends
FROM friends_map
WHERE user_id = 1
GROUP BY user_id
或者使用一些 key : value
对,因为 json 允许这样做,所以你的输出会更 语义 如果你喜欢的话:
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;
您可以使用:array[]
就这样做:
SELECT user_id, array[friend_id, confirmed]
FROM friend_map
WHERE user_id = 1
GROUP BY 1;