当前位置: 首页 > 面试题库 >

如何在PostgreSQL的“分组依据”查询中串联字符串字段的字符串?

狄新立
2023-03-14
问题内容

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

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


问题答案:

PostgreSQL 9.0或更高版本:

Postgres的最新版本(自2010年末开始)具有string_agg(expression, delimiter)可以完全满足问题要求的功能,甚至允许您指定分隔符字符串:

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

Postgres
9.0还增加了在任何聚合表达式中指定ORDER BY子句的功能;否则,顺序是不确定的。因此,您现在可以编写:

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

或确实是:

SELECT string_agg(actor_name, ', ' ORDER BY first_appearance)

PostgreSQL 8.4或更高版本:

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;

string_agg 对于8.4之前的版本:

如果有人遇到这种情况,希望为9.0之前版本的数据库提供兼容的填充程序,则可以实现string_aggORDER BY子句以外的所有内容。

因此,使用以下定义,它应与9.x Postgres DB中的工作相同:

SELECT string_agg(name, '; ') AS semi_colon_separated_names FROM things;

但这将是语法错误:

SELECT string_agg(name, '; ' ORDER BY name) AS semi_colon_separated_names FROM things;
--> ERROR: syntax error at or near "ORDER"

已在PostgreSQL 8.3上测试。

CREATE FUNCTION string_agg_transfn(text, text, text)
    RETURNS text AS 
    $$
        BEGIN
            IF $1 IS NULL THEN
                RETURN $2;
            ELSE
                RETURN $1 || $3 || $2;
            END IF;
        END;
    $$
    LANGUAGE plpgsql IMMUTABLE
COST 1;

CREATE AGGREGATE string_agg(text, text) (
    SFUNC=string_agg_transfn,
    STYPE=text
);

自定义版本(所有Postgres版本)

9.0之前的版本没有内置的聚合函数来连接字符串。最简单的自定义实现(由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;


 类似资料:
  • 本文向大家介绍MySQL查询以字符串字段中的数字字符对行进行分组?,包括了MySQL查询以字符串字段中的数字字符对行进行分组?的使用技巧和注意事项,需要的朋友参考一下 为此,您可以在+运算符的帮助下将0与字符串字段连接起来。这里的场景就像我们需要从字符串字段“ 9844Bob ”中获取数字“ 9844 ”。 让我们首先创建一个表- 使用插入命令在表中插入一些记录- 使用select语句显示表中的所

  • 问题内容: 我在C#中使用elasticsearch.net库,并尝试查询与指定过滤器匹配的对象。 我希望查询返回对象,其中对象的Names集合中至少存在来自过滤器的输入名称之一。 问题是此查询的结果总是使我命中0次,即使我确定数据库中确实存在与指定过滤器匹配的数据,我也想找出我的查询出了什么问题… 该模型: 过滤对象: 查询数据的方法: 我也尝试过以下查询,但都没有产生预期的结果: 适用于我的解

  • 问题内容: 以下语句, 产生输出。 但是,以下内容 产生。 区别在哪里? 问题答案: 您会因为操作符优先级和字符串转换的结合而看到此行为。 JLS 15.18.1 指出: 如果只有一个操作数表达式的类型为String,则对另一操作数执行字符串转换(第5.1.11节),以在运行时生成字符串。 因此,第一个表达式中的右侧操作数将隐式转换为字符串: 但是对于第二个表达式,必须将复合赋值运算符与一起考虑。

  • 我有一个字符串数组,我想查找具有字段且值包含在数组中的所有文档。 例如,假设我有数组< code>kidsInTrouble = ["Jerry "," Tom "," Arnold"], 我想搜索我的学生集合,以找到< code>name字段为< code>"Jerry" 、< code>"Tom"或< code>"Arnold"的所有孩子。 (如果可以使用Spring的Mongo驱动程序方法提

  • 问题内容: 我想知道如何在Java中连接4个字符串数组。 已经有一个问题了。 如何在Java中连接两个数组? 但是我试图复制它,但是它对我不起作用。 这是我的代码如下所示: 调用方法: 方法本身: 问题答案: 抛开诸如检查数组是否为的事情null,您可以为其创建通用方法,并在您的特定情况下使用它,如下所示:

  • 问题内容: 在将根据循环被重复。如何将结果另存为新字符串。例如,如果工作“ hello”重复了两次,我现在将如何创建“ hellohello”作为一个全新的字符串。 问题答案: