我正在寻找一种方法,通过查询将组中字段的字符串连接起来.例如,我有一张桌子:

ID   COMPANY_ID   EMPLOYEE
1    1            Anna
2    1            Bill
3    2            Carol
4    2            Dave

我想按公司id分组,得到如下信息:

COMPANY_ID   EMPLOYEE
1            Anna, Bill
2            Carol, Dave

mySQL中有一个内置函数来实现这一点

推荐答案

PostgreSQL 9.0或更高版本:

现代Postgres(自2010年起)有string_agg(expression, delimiter)个功能,可以完全满足提问者的要求:

SELECT company_id, string_agg(employee, ', ')
FROM mytable
GROUP BY company_id;

Postgres 9还增加了指定ORDER BYin any aggregate expression条的能力;否则,您必须对所有结果进行排序,或者处理未定义的顺序.所以你现在可以写:

SELECT company_id, string_agg(employee, ', ' ORDER BY employee)
FROM mytable
GROUP BY company_id;

PostgreSQL 8.4.x:

PostgreSQL 8.4(2009年)引入了the aggregate function 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及以上:

最初提出这个问题时,没有内置的聚合函数来连接字符串.最简单的自定义实现(suggested by Vajda Gabo in this mailing list post等)是使用内置textcat函数(位于||运算符后面):

CREATE AGGREGATE textcat_all(
  basetype    = text,
  sfunc       = textcat,
  stype       = text,
  initcond    = ''
);

Here is the CREATE AGGREGATE documentation.

这只是把所有的线粘在一起,没有分隔符.为了在它们之间插入一个","而不在末尾,您可能需要创建自己的连接函数,并用它代替上面的"textcat".1.8和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;

Sql相关问答推荐

重复ID消除跨越两列

Postgres,使用iLike运算符从json数组中搜索的工作方式与从常规表中搜索不同

在甲骨文中查找前一个星期一的S日期

Access 365将文本转换回BigInt

在Postgres中实现合并功能的干净方法,因为当目标/源不匹配时

当交叉联接3个或更多表时,实体框架中是否会传输冗余的行数据并占用数据库带宽?

如何在postgres函数中插入后返回布尔值?

关于Postgres横向联接的谓词

将结果从一列转换为两行或更多

Select 最频繁的值以及分组依据

SQL中相同表内的VLOOKUP等价

如何判断小数点后千位是否不为0

Snowflake中的动态SQL优化

正则表达式忽略特定数据部分的分隔符

将表格和字符串连接以 for each 记录生成订单项目

PostgreSQL - 递归地聚合来自不同列的属性

SQL - 只需要 GROUP BY SELECT 的一列

根据条件列出不同的值

根据开始/结束标记将 GROUP_ID 分配给行

将单行中的多个行值转换为列