【发布时间】:2013-03-28 15:36:30
【问题描述】:
我有一张这样的桌子
Movie Actor
A 1
A 2
A 3
B 4
我想获取电影的名称以及该电影中的所有演员,并且我希望结果采用如下格式:
Movie ActorList
A 1, 2, 3
我该怎么做?
【问题讨论】:
标签: sql postgresql aggregate-functions
我有一张这样的桌子
Movie Actor
A 1
A 2
A 3
B 4
我想获取电影的名称以及该电影中的所有演员,并且我希望结果采用如下格式:
Movie ActorList
A 1, 2, 3
我该怎么做?
【问题讨论】:
标签: sql postgresql aggregate-functions
您可以为此使用array_agg 函数:
SELECT "Movie",
array_to_string(array_agg(distinct "Actor"),',') AS Actor
FROM Table1
GROUP BY "Movie";
结果:
| MOVIE | ACTOR |
|---|---|
| A | 1,2,3 |
| B | 4 |
【讨论】:
使用聚合函数string_agg()(Postgres 9.0 或更高版本)更简单:
SELECT movie, string_agg(actor, ', ') AS actor_list
FROM tbl
GROUP BY 1;
GROUP BY 1 中的 1 在这种情况下是GROUP BY movie 的位置参考和快捷方式。
string_agg() 需要数据类型 text 作为输入。其他类型需要显式转换 (actor::text) - 除非 隐式转换为 text 已定义 - 所有其他字符类型都是这种情况 (varchar, character, @ 987654336@) 等一些类型。
作为isapir commented,您可以在聚合调用中添加ORDER BY 子句以获取排序列表——如果您需要的话。喜欢:
SELECT movie, string_agg(actor, ', ' ORDER BY actor) AS actor_list
FROM tbl
GROUP BY 1;
但在子查询中对行进行排序通常更快。见:
【讨论】:
SELECT 列表中的复杂表达式或动态SQL。
actor 是INT,则可能需要actor::TEXT。至少,我在 Postgres 9.5 中尝试 string_agg INTs 时遇到错误 - 但除此之外,这正是我所需要的,谢谢!
ORDER BY 子句可以在分隔符参数之后进入string_agg 函数,例如string_agg(actor, ', ' ORDER BY actor DESC)