PostgreSQL 9.0及以上版本:
现代Postgres(自2010年以来)有string_agg(表达式,分隔符)函数,它将做的正是询问者正在寻找的:
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(表达式),用于收集数组中的值。然后可以使用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;