Sql server MS-SQL将多行、多列合并为一条记录?

Sql server MS-SQL将多行、多列合并为一条记录?,sql-server,string-aggregation,Sql Server,String Aggregation,MS-SQL 假设我有一个名为dbo.students的表,其字段如下 受试学生名称学生名称 ----------      -------------  ------------ 玛丽Abc 1约翰·迪夫斯 1 Sam Ghix 2 Alaina Jklxx 2爱德华·姆诺基www 我预期的结果是: 主语学生名 ----------      ------------- 1玛丽·Abc、约翰·迪夫斯、山姆·吉克斯 2 Alaina Jklxx,Edward Mnoqwww 我知道如何将

MS-SQL

假设我有一个名为dbo.students的表,其字段如下


受试学生名称学生名称
----------      -------------  ------------
玛丽Abc
1约翰·迪夫斯
1 Sam Ghix
2 Alaina Jklxx
2爱德华·姆诺基www

我预期的结果是:


主语学生名
----------      -------------
1玛丽·Abc、约翰·迪夫斯、山姆·吉克斯
2 Alaina Jklxx,Edward Mnoqwww


我知道如何将StudentfName和StudentsName组合为StudentName,不过我想使用SubjectID中的唯一值将所有名称组合在一行中?

如果是sql server VNext>=2017,则可以使用string\u agg函数

select subjectid, string_agg(studentName,', ') from yourtable
    group by subjectid
对于早期版本,您需要使用以下内容和自定义代码:

select subjectid,  stuff(( select concat( ',', studentfname, ' ', studentsname) from #yourstudent y where y.subjectid = u.subjectid for xml path('')),1,1, '') 
    from #yourstudent u
    group by subjectid
您的表输入数据:

create table #yourstudent (subjectid int, studentfname varchar(10), studentsname varchar(10))

insert into #yourstudent (subjectid, studentfname, studentsname) values
 ( 1       ,'Mary','Abc')
,( 1       ,'John','Defs')
,( 1       ,'Sam','Ghix')
,( 2       ,'Alaina','Jklxx  ')
,( 2       ,'Edward','Mnoqwww')
希望这能奏效

select
    SubjectID,
    stuff((
        select ',' + t.[StudentfName]+ ' ' +t.[StudentsName]
        from #your_table t
        where t.SubjectID = t1.SubjectID
        order by t.SubjectID
        for xml path('')
    ),1,1,'') as StudentName
from #your_table t1
group by SubjectID; 

这称为字符串聚合或分组连接

有多种技术。所有这些都在亚伦·伯特兰的文章中有描述

使用最快、最简单的方法是创建和使用SQLCLR聚合。正如Aaron Bertrand所做的那样:

SELECT 
   SubjectID, 
   dbo.GROUP_CONCAT_S(StudentfName + ' ' + StudentsName, 1)
FROM dbo.Students
GROUP BY SubjectID
ORDER BY SubjectID;
编写和部署SQLCLR聚合需要几个步骤,但内存、性能和可用性方面的好处是显著的

SQL Server 2017将提供比SQLCLR更快的本机
STRING_AGG
,例如:

SELECT 
   SubjectID, 
   STRING_AGG(StudentfName + ' ' + StudentsName, 1)
FROM dbo.Students
GROUP BY SubjectID
ORDER BY SubjectID;
接下来是XML路径。打字比较容易,但使用起来不是那么容易。本质上,您可以将所有字段转换为XML元素,并使用空字符串作为元素标记将其与XPATH组合:

SELECT SubjectID, 
       Students = STUFF((SELECT N', ' + 
                         StudentfName + ' ' + StudentsName
                         FROM Students AS p2
                         WHERE p2.SubjectID = p.SubjectID 
                         ORDER BY StudentfName, StudentsName
                         FOR XML PATH(N''), TYPE).value(N'.[1]', N'nvarchar(max)')
                      ,1, 2, N'')
FROM Students AS p
GROUP BY subjectid
ORDER BY subjectid;

请注意
路径,TYPE).value(…)
函数。如果字段中包含任何对XML有特殊意义的字符,如
,那么不妨解释一下它的作用和来源。谢谢,基于示例,。。concat失败,不幸的是SQL 2008 r2无法使用。当我在ID上使用GROUP BY(在我的情况下,我的应用程序使用不同的表)时,我选择的字段上会出现错误,如果我将该字段添加到组中,则select中的下一个字段会失败(依此类推)与此相同的错误:列“dbo.AB_AB_ABC.State”在选择列表中无效,因为它未包含在聚合函数或GROUP BY子句中。
XML PATH
本身将失败,如果文本包含
&
它是名称,我认为它们不会有特殊字符。。。如果是问题海报可能会提供样本数据…你的意思是像
O'Reilly
?Aaron Bertrand的文章介绍了如何使用
XML路径
进行字符串聚合,这些文章解释了这个问题。他还解释了为什么他不使用
varchar
,因为表格可能包含非拉丁文本。我之所以使用SQLCLR聚合,是因为它是最快、最容易使用的
SELECT SubjectID, 
       Students = STUFF((SELECT N', ' + 
                         StudentfName + ' ' + StudentsName
                         FROM Students AS p2
                         WHERE p2.SubjectID = p.SubjectID 
                         ORDER BY StudentfName, StudentsName
                         FOR XML PATH(N''), TYPE).value(N'.[1]', N'nvarchar(max)')
                      ,1, 2, N'')
FROM Students AS p
GROUP BY subjectid
ORDER BY subjectid;