GROUP_CONCAT是MySQL独占函数,PostgreSQL和SQL Server不支持,会报错;STRING_AGG是后两者的标准方案,但语法细节不同:PostgreSQL要求STRING_AGG(expr, delim ORDER BY ...),SQL Server需WITHIN GROUP(ORDER BY ...),且均默认跳过NULL、不设长度硬限制。

GROUP_CONCAT 只能在 MySQL 里用
别在 PostgreSQL 或 SQL Server 里写 GROUP_CONCAT,它会直接报错 Unknown function 'GROUP_CONCAT'。这个函数是 MySQL 独占的,连 MariaDB 虽然兼容,但版本低于 10.3.3 的也不支持完整语法(比如 ORDER BY 子句)。如果你看到别人代码里用了,先确认数据库类型——不是“写法更短”就代表通用。
STRING_AGG 是 PostgreSQL 和 SQL Server 2017+ 的标准方案
STRING_AGG 在 PostgreSQL 和较新 SQL Server 中行为一致,但细节仍有差异:
- PostgreSQL:必须显式提供分隔符,且
ORDER BY必须写在函数括号内,例如STRING_AGG(name, ', ' ORDER BY id) - SQL Server:同样要求
WITHIN GROUP (ORDER BY id),漏掉WITHIN GROUP就报错Incorrect syntax near the keyword 'ORDER' - 两者都不接受列名或表达式作分隔符,
STRING_AGG(name, delim_col)会失败
超长字符串被静默截断?大概率是 GROUP_CONCAT
MySQL 的 GROUP_CONCAT 默认只拼前 1024 字符,超出部分直接丢弃,不报错、不警告。你查出来的结果“少了一半”,八成是这个原因。
- 查当前限制:
SELECT @@group_concat_max_len - 临时调高(当前会话):
SET SESSION group_concat_max_len = 1000000 - 永久生效要改
my.cnf并重启,不是 ALTER TABLE 或 SET GLOBAL 就能搞定 - PostgreSQL 的
STRING_AGG没这个硬限制,但若work_mem不足,可能触发磁盘排序,查EXPLAIN ANALYZE看是否有 “Sort Method: external merge”
NULL 值处理方式不同,不兜底容易崩上游逻辑
两个函数都默认跳过 NULL,但整组全为 NULL 时表现相反:
-
GROUP_CONCAT返回NULL(不是空字符串) -
STRING_AGG同样返回NULL,但 PostgreSQL 9.0+ 和 SQL Server 都不自动转空串 - 安全写法统一用
COALESCE(STRING_AGG(...), '')或IFNULL(GROUP_CONCAT(...), '') - 想把 NULL 显式转成
'(null)',得提前用COALESCE(col, '(null)')或IFNULL(col, '(null)')
最常被忽略的是排序依赖——没写 ORDER BY 时,拼出的字符串顺序由执行计划决定,哪怕表数据没变,两次查询结果也可能不同。


















