SQL Server 2022 中使用 STRING_AGG 必须同时满足三个硬性条件:版本确认(@@VERSION 含“2022”且兼容级别≥160)、必须配合 GROUP BY 使用、排序必须显式声明 WITHIN GROUP(ORDER BY)。

SQL Server 2022 中能直接用 STRING_AGG,但写错一个位置或漏掉一个条件,就会报错或结果乱序——不是函数不行,是它有三个硬性约束必须同时满足。
确认版本和兼容级别是否真支持 STRING_AGG
光看安装包叫“SQL Server 2022”没用,得实锤。运行这两条:
-
SELECT @@VERSION;—— 输出必须含Microsoft SQL Server 2022(不能只是16.x) -
SELECT DATABASEPROPERTYEX(DB_NAME(), 'CompatibilityLevel');—— 结果必须 ≥160
如果第二条返回 150(2019)或更低,哪怕版本是对的,STRING_AGG 也会被当作不存在。立刻执行:ALTER DATABASE CURRENT SET COMPATIBILITY_LEVEL = 160;
STRING_AGG 必须跟 GROUP BY 配对,不能裸用
它和 COUNT()、SUM() 是同一类聚合函数,没有分组维度,SQL Server 直接拒绝执行。
- ❌ 错误写法:
SELECT STRING_AGG(name, ', ') FROM users;→ 报错STRING_AGG is not allowed in the context - ✅ 正确写法(按部门分组):
SELECT dept_id, STRING_AGG(name, '; ') FROM users GROUP BY dept_id; - ✅ 全表拼一行(绕过语法限制):
SELECT STRING_AGG(name, ', ') FROM (SELECT name FROM users) t GROUP BY (SELECT NULL);
排序必须用 WITHIN GROUP (ORDER BY ...),且字段受限
不加 WITHIN GROUP,结果顺序是未定义的——哪怕表有主键或聚集索引,下次执行可能就变。
- ✅ 正确写法:
STRING_AGG(name, ', ') WITHIN GROUP (ORDER BY hire_date DESC) - ❌ 错误写法:
STRING_AGG(name, ', ') ORDER BY hire_date→ 语法错误 - ⚠️ 注意:
ORDER BY里的字段必须出现在GROUP BY子句中,或为聚合表达式(如MIN(hire_date)),不能是未分组的裸列 - ⚠️ 分隔符不能为
NULL;非字符串字段(如id int)要显式转:CAST(id AS VARCHAR)
STRING_AGG 默认跳过 NULL,空字符串会被保留
这是最容易被忽略的行为差异:空值(NULL)直接消失,但空字符串('')会参与拼接,还带分隔符。
- 想把
NULL显式转成占位符(比如'(unknown)'),得提前处理:STRING_AGG(ISNULL(name, '(unknown)'), ', ') - 想过滤掉空字符串,得在子查询里加
WHERE name != '' - 换行符要用
CHAR(13)+CHAR(10),别写E'\n'(那是 PostgreSQL 的)
真正麻烦的不是语法本身,而是它强制你思考分组逻辑、排序依赖和空值语义——这三个点只要漏一个,结果就不可靠。










