我有一个类似这样的表格:
电影 | 演员 |
---|---|
A | 1 |
A | 2 |
A | 3 |
B | 4 |
我想得到一部电影的名称以及所有出演该电影的演员,并且我希望结果的格式如下:
电影 | 演员列表 |
---|---|
A | 1,2,3 |
我应该怎么做呢?
我有一个类似这样的表格:
电影 | 演员 |
---|---|
A | 1 |
A | 2 |
A | 3 |
B | 4 |
我想得到一部电影的名称以及所有出演该电影的演员,并且我希望结果的格式如下:
电影 | 演员列表 |
---|---|
A | 1,2,3 |
我应该怎么做呢?
使用聚合函数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
、name
等)和某些其他类型是适用的。
正如 isapir 评论的,您可以在聚合调用中添加 ORDER BY
子句以获取有序列表 - 如果您需要的话。例如:
SELECT movie, string_agg(actor, ', ' <b>ORDER BY actor</b>) AS actor_list
FROM tbl
GROUP BY 1;
但通常在子查询中对行进行排序速度更快。请参见:
SELECT
列表中或使用动态SQL中的复杂表达式。 - Erwin Brandstetteractor
是一个 INT
,可能需要使用 actor::TEXT
。在 Postgres 9.5 中尝试使用 string_agg
聚合 INT
时会出现错误 - 但除此之外,这正是我所需要的,谢谢! - dwandersonstring_agg
函数可以加上一个可选的 ORDER BY
子句,例如:string_agg(actor, ', ' ORDER BY actor DESC)
。 - isapirarray_agg
函数进行相关操作:SELECT "Movie",
array_to_string(array_agg(distinct "Actor"),',') AS Actor
FROM Table1
GROUP BY "Movie";
结果:
电影 | 演员 |
---|---|
A | 1,2,3 |
B | 4 |
更多信息,请参见9.18. 聚合函数