PostgreSQL新手问题:如何聚合玩家对应的投票周为列表?
PostgreSQL实现玩家投票周数的列表化查询
当然可以实现,你需要通过分组聚合来将每个玩家的所有投票周数合并成一个列表,避免name重复显示。以下是具体解决方案:
核心思路
通过GROUP BY按玩家的唯一标识(players.id)和姓名分组,再使用PostgreSQL提供的聚合函数将同一玩家的所有week值合并为数组或字符串形式。
具体查询示例
1. 返回数组格式的周数列表
适合后续需要对周数进行数组操作的场景:
SELECT p.name, array_agg(v.week) AS week_list FROM public.players p JOIN public.votes v ON v.player_id = p.id GROUP BY p.id, p.name;
2. 去重并排序的数组列表
如果存在同一玩家同一周多次投票的情况,或者需要周数按顺序排列:
SELECT p.name, array_agg(DISTINCT v.week ORDER BY v.week) AS sorted_unique_week_list FROM public.players p JOIN public.votes v ON v.player_id = p.id GROUP BY p.id, p.name;
3. 返回逗号分隔的字符串列表
适合直接展示的场景:
SELECT p.name, string_agg(v.week::text, ', ') AS week_string_list FROM public.players p JOIN public.votes v ON v.player_id = p.id GROUP BY p.id, p.name;
4. 包含无投票记录的玩家
如果需要列出所有玩家,即使没有投票记录(此时周数列表为空):
SELECT p.name, coalesce(array_agg(v.week), '{}'::integer[]) AS week_list FROM public.players p LEFT JOIN public.votes v ON v.player_id = p.id GROUP BY p.id, p.name;
关键说明
- 必须按
p.id分组:避免因存在同名玩家导致分组错误,p.name可一同加入GROUP BY(PostgreSQL支持在分组中包含与分组键一一对应的非聚合字段)。 array_agg:将聚合字段值转为PostgreSQL数组类型;string_agg:转为指定分隔符的字符串。coalesce:处理无投票记录的玩家,将NULL替换为空数组。
内容的提问来源于stack exchange,提问作者Simon H
相关产品推荐
相关产品推荐

