PostgreSQL 9.0 或更高版本:
现代 Postgres(自 2010 年以来)具有string_agg(expression, delimiter)
完全符合提问者要求的功能:
SELECT company_id, string_agg(employee, ', ')
FROM mytable
GROUP BY company_id;
Postgres 9 还增加了在任何聚合表达式中指定ORDER BY
子句的能力;否则,您必须订购所有结果或处理未定义的订单。所以你现在可以写:
SELECT company_id, string_agg(employee, ', ' ORDER BY employee)
FROM mytable
GROUP BY company_id;
PostgreSQL 8.4.x:
PostgreSQL 8.4(2009 年)引入了聚合函数array_agg(expression)
,它收集数组中的值。然后array_to_string()
可以用来给出想要的结果:
SELECT company_id, array_to_string(array_agg(employee), ', ')
FROM mytable
GROUP BY company_id;
PostgreSQL 8.3.x 及更早版本:
最初提出这个问题时,没有内置的聚合函数来连接字符串。最简单的自定义实现(由 Vajda Gabo 在此邮件列表帖子中提出的建议)是使用内置textcat
函数(位于||
操作符后面):
CREATE AGGREGATE textcat_all(
basetype = text,
sfunc = textcat,
stype = text,
initcond = ''
);
这是CREATE AGGREGATE
文档。
这只是将所有字符串粘合在一起,没有分隔符。为了在它们之间插入“,”而不在末尾插入,您可能需要创建自己的连接函数并将其替换为上面的“textcat”。这是我放在一起并在 8.3.12 上测试的一个:
CREATE FUNCTION commacat(acc text, instr text) RETURNS text AS $$
BEGIN
IF acc IS NULL OR acc = '' THEN
RETURN instr;
ELSE
RETURN acc || ', ' || instr;
END IF;
END;
$$ LANGUAGE plpgsql;
即使该行中的值为 null 或空,此版本也会输出逗号,因此您会得到如下输出:
a, b, c, , e, , g
如果您希望删除多余的逗号来输出:
a, b, c, e, g
然后像这样向函数添加一个ELSIF
检查:
CREATE FUNCTION commacat_ignore_nulls(acc text, instr text) RETURNS text AS $$
BEGIN
IF acc IS NULL OR acc = '' THEN
RETURN instr;
ELSIF instr IS NULL OR instr = '' THEN
RETURN acc;
ELSE
RETURN acc || ', ' || instr;
END IF;
END;
$$ LANGUAGE plpgsql;