2010-04-01 84 views
169

我有一个表,我想每个ID拉字段值连接一行。Postgresql GROUP_CONCAT等效?

在我的表,例如,我有这样的:

TM67 | 4 | 32556 
TM67 | 9 | 98200 
TM67 | 72 | 22300 
TM99 | 2 | 23009 
TM99 | 3 | 11200 

而且想我输出:

TM67 | 4,9,72 | 32556,98200,22300 
TM99 | 2,3 | 23009,11200 

在MySQL中我能够使用聚合函数GROUP_CONCAT,但这似乎不工作在这里...是否有相当于PostgreSQL,或另一种方式来实现这一目标?

+0

不是一个答案,但检查出http://www.postgresonline.com/journal/index.php? /archives/14-CrossTab-Queries-in-PostgreSQL-using-tablefunc-contrib.html。 – Kuberchaun 2010-04-01 14:21:49

+1

http://stackoverflow.com/questions/1943433/postgresql-concat-ws-like-function – 2010-04-01 15:41:26

+0

可能重复[在SQL Server中模拟组\ _concat MySQL函数?](http://stackoverflow.com/questions/451415/simulating-group-concat-mysql-function-in-sql-server) – ntalbs 2015-02-10 03:49:09

回答

155

这可能是一个很好的起点(版本8.4+只):

SELECT id_field, array_agg(value_field1), array_agg(value_field2) 
FROM data_table 
GROUP BY id_field 

array_agg返回一个数组,但你可以强制转换为需要的文本和编辑(见澄清,下同)。

此前8.4版本,你必须定义它自己使用前:

CREATE AGGREGATE array_agg (anyelement) 
(
    sfunc = array_append, 
    stype = anyarray, 
    initcond = '{}' 
); 

(从PostgreSQL文档意译)

澄清:

  • 铸造的结果数组到文本是生成的字符串以花括号开始和结束。这些大括号需要通过某种方法删除,如果他们不需要。
  • 将ANYARRAY投射到TEXT最能模拟CSV输出,因为包含嵌入逗号的元素在标准CSV样式的输出中被双引号引用。无论是array_to_string()还是string_agg()(9.1中添加了“group_concat”函数)都会引用带有嵌入逗号的字符串,从而导致结果列表中的元素数量不正确。
  • 新的9.1 string_agg()函数不会先将内部结果转换为TEXT。所以如果value_field是一个整数,那么“string_agg(value_field)”会产生一个错误。 “string_agg(value_field :: text)”将是必需的。 array_agg()方法在聚合之后只需要一次强制转换(而不是每个值的强制转换)。
+0

而在9。0您将有LISTAGG() – 2010-04-01 16:55:29

+4

要获得CSV查询应该是: SELECT id_field,array_to_string(ARRAY_AGG(value_field1), ' '),array_to_string(ARRAY_AGG(value_field2),'') FROM data_table GROUP BY id_field – Nux 2012-02-16 16:08:34

+2

在这里的所有情况下都不能使用array_to_string。如果您的value_field包含嵌入的逗号,则结果CSV不正确。使用array_agg()并将其转换为TEXT可以正确引用带有嵌入逗号的字符串。唯一需要注意的是,它还包括起始和结束花括号,因此我的声明是“并根据需要进行编辑”。我会编辑以澄清这一点。 – 2012-02-21 20:00:56

30
SELECT array_to_string(array(SELECT a FROM b),', '); 

也将这样做。

+4

这个也在9.0之前工作 - 用8.4测试它。 5 – chrpes 2013-08-16 09:59:25

+0

超凡!适用于我。 Teste也是Postgres 8.3.6。坦克! – vandersondf 2014-06-18 19:02:29

+0

是否可以在[此评论]中执行某些操作(http://stackoverflow.com/questions/2560946/postgresql-group-concat-equivalent#comment23843695_8803563),您是按照某个顺序进行聚合的?你将如何处理一列的分组和另一列的排序(例如,连接纵向数据集内的变量)? – 2015-01-08 18:22:26

178

Since 9.0这是更简单:

SELECT id, 
     string_agg(some_column, ',') 
FROM the_table 
GROUP BY id 
+18

请注意,该语法还允许您指定字符串(或数组,使用'array_agg')的值的顺序,例如'string_agg(some_column,','ORDER BY some_column)'或者甚至'string_agg(surname ||','|| forename,';'ORDER BY surname,forename)' – IMSoP 2013-05-16 14:33:36

+0

@a_horse_with_no_name我看到很多关于你的好帖子所以我正在处理各种Postgres问题。我没有办法在您的个人资料中与您联系。您是否愿意沟通/处理SO之外的项目?如果不是,请通过评论来表示歉意。如果您愿意接受SO之外的合作/工作,如果可以的话,您可以通过我的个人资料与我联系:http://stackoverflow.com/users/2565593/steve-midgley - 您在这里完成了令人惊叹的工作 - 谢谢您! (对于编辑,我依靠这样的元评论来留下评论:http://meta.stackexchange.com/a/58715/278168) – 2015-02-14 20:48:47

8

尝试这样的:

select field1, array_to_string(array_agg(field2), ',') 
from table1 
group by field1; 
相关问题