我正在寻找一种方法,通过查询连接组内字段的字符串。例如,我有一个表格:

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

我想通过company_id进行分组,以获得如下内容:

COMPANY_ID   EMPLOYEE
1            Anna, Bill
2            Carol, Dave

mySQL中有一个内置函数来执行这个group_concat


当前回答

如何使用Postgres内置数组函数?至少在8.4中,这是开箱即用的:

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

其他回答

根据PostgreSQL 9.0及以上版本,你可以使用名为string_agg的聚合函数。你的新SQL应该看起来像这样:

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

这个答案不是我的功劳,因为我是经过一番搜索才找到的:

我不知道的是PostgreSQL允许你用CREATE aggregate定义你自己的聚合函数

PostgreSQL列表上的这篇文章展示了创建一个函数来做所需的事情是多么简单:

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

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

你也可以使用format函数。它本身也可以隐式地处理text、int等类型转换。

create or replace function concat_return_row_count(tbl_name text, column_name text, value int)
returns integer as $row_count$
declare
total integer;
begin
    EXECUTE format('select count(*) from %s WHERE %s = %s', tbl_name, column_name, value) INTO total;
    return total;
end;
$row_count$ language plpgsql;


postgres=# select concat_return_row_count('tbl_name','column_name',2); --2 is the value

从PostgreSQL 9.0开始,你可以使用名为string_agg的聚合函数。你的新SQL应该看起来像这样:SELECT company_id, string_agg(employee, ', ') 从mytable GROUP BY company_id;

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;