Postgresql等价GROUP_CONCAT ?

我有一个表,我想拉一行每个id与字段值连接。

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

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有类似的功能吗,或者有其他方法可以实现这个功能?

235295 次浏览

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

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

array_agg返回一个数组,但你可以将其CAST为文本并根据需要进行编辑(参见下面的说明)。

在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()方法只需要在聚合之后进行一次强制转换(而不是对每个值进行强制转换)。
SELECT array_to_string(array(SELECT a FROM b),', ');

也行。

自9.0年这更简单:

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

试着这样做:

select field1, array_to_string(array_agg(field2), ',')
from table1
group by field1;

我在postgresql中的建议

SELECT cpf || ';' || nome || ';' || telefone
FROM (
SELECT cpf
,nome
,STRING_AGG(CONCAT_WS( ';' , DDD_1, TELEFONE_1),';') AS telefone
FROM (
SELECT DISTINCT *
FROM temp_bd
ORDER BY cpf DESC ) AS y
GROUP BY 1,2 ) AS x

和用于数组类型的版本:

select
array_to_string(
array(select distinct unnest(zip_codes) from table),
', '
);

希望下面的Oracle查询能正常工作。

Select First_column,LISTAGG(second_column,',')
WITHIN GROUP (ORDER BY second_column) as Sec_column,
LISTAGG(third_column,',')
WITHIN GROUP (ORDER BY second_column) as thrd_column
FROM tablename
GROUP BY first_column

假设表your_table有三列(name, id, value),查询如下:

  select name,
array_to_string(array_agg(id), ','),
array_to_string(array_agg(value), ',')
from your_table
group by name
order by name
;


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

KI

根据我的经验,我使用bigint作为列类型。所以下面的代码为我工作。我使用的是PostgreSQL 12。

类型转换发生在这里。(::文本)

string_agg(some_column::text, ',')