Sql server MS-SQL将多行、多列合并为一条记录?
MS-SQL 假设我有一个名为dbo.students的表,其字段如下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 我知道如何将
受试学生名称学生名称
---------- ------------- ------------
玛丽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;