MySQL中类似PostgreSQL中的string_agg函数--GROUP_CONCAT函数的使用

文章目录


结论:MySQL没有string_agg,但有GROUP_CONCAT

MySQL中没有直接等同于PostgreSQL的string_agg函数的内置函数,但你可以使用GROUP_CONCAT函数来实现类似的功能。GROUP_CONCAT函数可以将多个行的字符串值连接成一个字符串,类似于string_agg

GROUP_CONCAT函数的基本用法

GROUP_CONCAT函数的基本语法如下:

sql 复制代码
GROUP_CONCAT([DISTINCT] expr [,expr,...] [ORDER BY expr [ASC | DESC]] [SEPARATOR separator])
  • expr:要连接的表达式。
  • DISTINCT:可选,用于指定在连接字符串之前删除重复值。
  • ORDER BY:可选,用于指定连接字符串中值的顺序。
  • SEPARATOR:可选,用于指定连接字符串中值之间的分隔符,默认为逗号。

示例

假设你有一个名为employees的表,其中包含namedepartment列。你可以使用GROUP_CONCAT函数来获取每个部门的所有员工姓名,如下所示:

sql 复制代码
SELECT department, GROUP_CONCAT(name ORDER BY name ASC SEPARATOR ', ') AS employees
FROM employees
GROUP BY department;

这个查询将返回每个部门及其所有员工的姓名,员工姓名按字母顺序排列,并以逗号和空格分隔。

注意事项

  • GROUP_CONCAT函数的结果是一个字符串,因此它的长度有限制。默认情况下,这个限制是1024个字符,但你可以通过设置group_concat_max_len系统变量来增加这个限制。
  • GROUP_CONCAT函数在MySQL 5.7及更高版本中可用。如果你使用的是MySQL 5.6或更早版本,你可能需要使用其他方法来实现类似的功能。

系统变量 group_concat_max_len 如何查看和设置

在MySQL中,group_concat_max_len是一个系统变量,用于控制GROUP_CONCAT函数返回的结果字符串的最大长度。你可以使用SHOW VARIABLES语句来查看当前的group_concat_max_len值,并使用SET语句来设置新的值。

查看当前的group_concat_max_len

要查看当前的group_concat_max_len值,可以使用以下SQL语句:

sql 复制代码
SHOW VARIABLES LIKE 'group_concat_max_len';

这将返回group_concat_max_len的当前值。

设置group_concat_max_len

要设置group_concat_max_len的值,可以使用以下SQL语句:

sql 复制代码
SET [GLOBAL | SESSION] group_concat_max_len = new_value;
  • GLOBAL:用于设置全局值,这将对所有新的客户端连接生效。
  • SESSION:用于设置会话值,这仅对当前客户端连接生效。
    例如,要将group_concat_max_len设置为1000000,可以使用以下SQL语句:
sql 复制代码
SET GLOBAL group_concat_max_len = 1000000;

或者,仅对当前会话设置:

sql 复制代码
SET SESSION group_concat_max_len = 1000000;

请注意,增加group_concat_max_len的值可能会导致内存使用量增加,因此在设置较大的值时需要谨慎。

相关源码

判断结果长度的相关源码:sql/item_sum.cc

Item_func_group_concat::add()

调用 dump_leaf_key(table->record0 + table->s->null_bytes, 1, this);

即:int dump_leaf_key(void *key_arg, element_count count \[maybe_unused],void *item_arg)

其中dump_leaf_key函数中的关键判断代码如下(正常返回0,异常返回1):

c++ 复制代码
int dump_leaf_key(void *key_arg, element_count count [[maybe_unused]],
                  void *item_arg) {
    
    ......
    
  /*
     Stop if the size of group_concat value, in bytes, is longer than
     the maximum size.
  */
  if (result->length() > item->group_concat_max_len) {
    int well_formed_error;
    const CHARSET_INFO *cs = item->collation.collation;
    const char *ptr = result->ptr();
    size_t add_length;
    /*
      It's ok to use item->result.length() as the fourth argument
      as this is never used to limit the length of the data.
      Cut is done with the third argument.
    */
    add_length = cs->cset->well_formed_len(
        cs, ptr + old_length, ptr + item->group_concat_max_len,
        result->length(), &well_formed_error);
    result->length(old_length + add_length);
    item->warning_for_row = true;
    push_warning_printf(
        current_thd, Sql_condition::SL_WARNING, ER_CUT_VALUE_GROUP_CONCAT,
        ER_THD(current_thd, ER_CUT_VALUE_GROUP_CONCAT), item->row_count);

    /**
       To avoid duplicated warnings in Item_func_group_concat::val_str()
    */
    if (table && table->blob_storage)
      table->blob_storage->set_truncated_value(false);
    return 1;
  }
  return 0;
}
	

相关链接

官方文档:https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_group-concat

相关推荐
安_29 分钟前
RAG的向量数据库:为LLM提供语义搜索能力
数据库
喜欢的名字被抢了1 小时前
程序出问题怎么查,以及如何让它不掉线
java·运维·数据库
这个DBA有点耶1 小时前
3000万个应用共享一套数据库:多租户“逻辑表”架构是如何做到的?
数据库·架构·dba
测试运维日常笔记2 小时前
Oracle 数据库连接认证方式详解
数据库·oracle
ClouGence2 小时前
PostgreSQL 同步到 Iceberg:开源、私有部署与 SaaS 方案对比
数据库·postgresql·开源
这个DBA有点耶3 小时前
DBA进阶之路:从“修数据库”到“管架构债”
数据库·架构·dba
ACP广源盛139246256733 小时前
WAIC2026 国产超节点算力浪潮下@ACP#IX9104 在算力矩阵中的定位与落地场景
大数据·数据库·人工智能·嵌入式硬件·线性代数·矩阵
珠***格4 小时前
通信链路全打通:西格电力四可装置的 4G/5G + 加密认证技术详解
大数据·数据库·分布式·5g·架构·能源
盗理者4 小时前
AI Agent 技能分享|从零实现 MCP Server,让 Agent 安全读取数据库
数据库·oracle
xqqxqxxq4 小时前
Redis 五大常用数据类型 + 通用命令笔记
数据库·redis·笔记