在SQL Server的实际业务开发中,经常会遇到需要将同一分组下的多条字符串记录合并为一条的需求,比如将某个部门下所有员工的姓名合并成一个字符串展示,或者将同一个订单下的所有商品名称拼接起来。传统的实现方式需要借助FOR XML PATH或者自定义函数,逻辑复杂且执行效率不高,而STRING_AGG函数的出现很好地解决了这个问题。

STRING_AGG函数基本语法
STRING_AGG是SQL Server 2017及后续版本新增的字符串聚合函数,它的核心作用是将分组内的字符串表达式按照指定的分隔符拼接起来,基本语法如下:
STRING_AGG ( expression, separator ) [ <order_clause> ] <order_clause> ::= WITHIN GROUP ( ORDER BY <order_by_expression_list> [ ASC | DESC ] )
参数说明:
- expression:要合并的字符串表达式,可以是列名、字符串常量或者返回字符串的表达式,类型需要是可隐式转换为VARCHAR或者NVARCHAR的类型。
- separator:用于分隔合并后字符串的分隔符,可以是单个字符或者字符串,比如逗号、竖线等。
- WITHIN GROUP (ORDER BY ...):可选参数,用于指定分组内字符串的合并顺序,默认是无序合并。
基础使用示例
我们先创建一个测试表,插入一些测试数据来演示STRING_AGG的用法,测试表存储了不同班级的学生姓名信息:
-- 创建测试表
CREATE TABLE StudentInfo (
ClassId INT,
StudentName NVARCHAR(50)
);
-- 插入测试数据
INSERT INTO StudentInfo (ClassId, StudentName) VALUES
(1, '张三'),
(1, '李四'),
(1, '王五'),
(2, '赵六'),
(2, '钱七');
现在需要按照班级分组,将每个班级的学生姓名用逗号分隔合并成一个字符串,使用STRING_AGG实现的SQL语句如下:
SELECT
ClassId,
STRING_AGG(StudentName, ',') AS StudentNames
FROM StudentInfo
GROUP BY ClassId;
执行上述语句后,会得到如下结果:
| ClassId | StudentNames |
|---|---|
| 1 | 张三,李四,王五 |
| 2 | 赵六,钱七 |
指定合并顺序的用法
如果希望合并后的字符串按照学生姓名的拼音顺序排列,可以加上WITHIN GROUP子句指定排序规则:
SELECT
ClassId,
STRING_AGG(StudentName, ',') WITHIN GROUP (ORDER BY StudentName ASC) AS StudentNames
FROM StudentInfo
GROUP BY ClassId;
执行后班级1的学生姓名会按照拼音升序排列,结果为李四,王五,张三,符合我们指定的排序要求。
处理NULL值的情况
如果待合并的字符串表达式中存在NULL值,STRING_AGG函数会直接忽略这些NULL值,不会将NULL拼接到结果中。比如我们给测试表插入一条学生姓名为NULL的记录:
INSERT INTO StudentInfo (ClassId, StudentName) VALUES (1, NULL);
再次执行基础的分组合并语句,班级1的合并结果仍然是张三,李四,王五,NULL值没有被纳入合并结果。如果需要将NULL值转换为指定内容再合并,可以配合ISNULL或者COALESCE函数使用:
SELECT
ClassId,
STRING_AGG(ISNULL(StudentName, '未知'), ',') AS StudentNames
FROM StudentInfo
GROUP BY ClassId;
此时班级1的合并结果会变为张三,李四,王五,未知,NULL值被替换成了指定的未知内容。
与传统实现方式对比
在STRING_AGG函数出现之前,SQL Server中实现分组字符串合并通常使用FOR XML PATH的方式,同样的需求用传统方式实现的SQL如下:
SELECT
ClassId,
STUFF((
SELECT ',' + StudentName
FROM StudentInfo t2
WHERE t2.ClassId = t1.ClassId
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 1, '') AS StudentNames
FROM StudentInfo t1
GROUP BY ClassId;
对比两种方式可以看出,STRING_AGG的语法更加简洁直观,不需要嵌套子查询,也不需要处理XML相关的转换逻辑,同时执行效率也更高,尤其是在处理大数据量的时候优势更明显。
使用注意事项
- STRING_AGG函数仅在SQL Server 2017及更高版本中可用,如果使用的是更低版本的SQL Server,无法直接使用该函数,只能选择传统实现方式。
- 合并后的字符串长度受表达式类型的限制,如果使用VARCHAR类型,最大长度为8000,NVARCHAR最大长度为4000,如果合并后的结果超过这个长度,需要先将表达式转换为VARCHAR(MAX)或者NVARCHAR(MAX)类型。
- 分隔符参数如果是字符串常量,需要放在单引号中,比如使用竖线作为分隔符时,参数要写成
'|',而不是|。
需要注意的是,当合并的字符串包含特殊字符时,STRING_AGG函数不会自动进行转义,需要开发者提前处理特殊字符,避免后续使用合并结果时出现解析错误。
SQL_ServerSTRING_AGG分组数据合并字符串处理修改时间:2026-06-21 18:15:36