【问题标题】:Concatenate multiple result rows of one column into one, group by another column [duplicate]将一列的多个结果行连接成一个,按另一列分组[重复]
【发布时间】: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


【解决方案1】:

您可以为此使用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

this SQLFiddle

更多信息请见9.18. Aggregate Functions

【讨论】:

  • string~agg和array-agg有什么区别?
【解决方案2】:

使用聚合函数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;

但在子查询中对行进行排序通常更快。见:

【讨论】:

  • 我不知道 Postgres 支持这样的位置列引用,也想不出任何好的理由使用它们,但除此之外,这是正确的。
  • @IMSoP:这只是我加入的一种语法便利。一个很好的用例是SELECT 列表中的复杂表达式或动态SQL。
  • 小注释 - 如果actorINT,则可能需要actor::TEXT。至少,我在 Postgres 9.5 中尝试 string_agg INTs 时遇到错误 - 但除此之外,这正是我所需要的,谢谢!
  • @Chris:可能是您的客户端设置有问题,与查询无关。考虑:stackoverflow.com/a/23568429/939860
  • 值得注意的是,可选的ORDER BY 子句可以在分隔符参数之后进入string_agg 函数,例如string_agg(actor, ', ' ORDER BY actor DESC)
猜你喜欢
  • 2022-01-08
  • 2012-12-16
  • 2016-11-27
  • 2021-03-28
  • 1970-01-01
  • 1970-01-01
  • 2018-02-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多