文章目录
- 结论:MySQL没有string_agg,但有GROUP_CONCAT
- GROUP_CONCAT函数的基本用法
- 示例
- 注意事项
- 系统变量 group_concat_max_len 如何查看和设置
- 查看当前的`group_concat_max_len`值
- 设置`group_concat_max_len`值
- 相关源码
- 相关链接
结论:MySQL没有string_agg,但有GROUP_CONCAT
MySQL中没有直接等同于PostgreSQL的string_agg
函数的内置函数,但你可以使用GROUP_CONCAT
函数来实现类似的功能。GROUP_CONCAT
函数可以将多个行的字符串值连接成一个字符串,类似于string_agg
。
GROUP_CONCAT函数的基本用法
GROUP_CONCAT
函数的基本语法如下:
GROUP_CONCAT([DISTINCT] expr [,expr,...] [ORDER BY expr [ASC | DESC]] [SEPARATOR separator])
expr
:要连接的表达式。DISTINCT
:可选,用于指定在连接字符串之前删除重复值。ORDER BY
:可选,用于指定连接字符串中值的顺序。SEPARATOR
:可选,用于指定连接字符串中值之间的分隔符,默认为逗号。
示例
假设你有一个名为employees
的表,其中包含name
和department
列。你可以使用GROUP_CONCAT
函数来获取每个部门的所有员工姓名,如下所示:
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语句:
SHOW VARIABLES LIKE 'group_concat_max_len';
这将返回group_concat_max_len
的当前值。
设置group_concat_max_len
值
要设置group_concat_max_len
的值,可以使用以下SQL语句:
SET [GLOBAL | SESSION] group_concat_max_len = new_value;
GLOBAL
:用于设置全局值,这将对所有新的客户端连接生效。SESSION
:用于设置会话值,这仅对当前客户端连接生效。
例如,要将group_concat_max_len
设置为1000000,可以使用以下SQL语句:
SET GLOBAL group_concat_max_len = 1000000;
或者,仅对当前会话设置:
SET SESSION group_concat_max_len = 1000000;
请注意,增加group_concat_max_len
的值可能会导致内存使用量增加,因此在设置较大的值时需要谨慎。
相关源码
判断结果长度的相关源码:sql/item_sum.cc
Item_func_group_concat::add()
调用 dump_leaf_key(table->record[0] + 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):
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