MS-SQL将多行,列组合成一条记录?

时间:2017-05-05 09:05:42

标签: sql-server string-aggregation

MS-SQL,..

假设我有一个名为dbo.students的表,其中包含

等字段

SubjectID       StudentfName   StudentsName ----------      -------------  ------------ 1               Mary           Abc 1               John           Defs 1               Sam            Ghix 2               Alaina         Jklxx 2               Edward         Mnoqwww

结果我期待的是:

SubjectID       StudentName ----------      ------------- 1               Mary Abc, John Defs, Sam Ghix 2               Alaina Jklxx, Edward Mnoqwww

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

4 个答案:

答案 0 :(得分:0)

如果是sql server VNext> = 2017则可以使用string_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')

答案 1 :(得分:0)

希望这会奏效,

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; 

答案 2 :(得分:0)

;WITH cte(SubjectID,StudentfName,StudentsName)
AS
(

SELECT 1,'Mary'  ,'Abc'     Union all
SELECT 1,'John'  ,'Defs'    Union all
SELECT 1,'Sam'   ,'Ghix'    Union all
SELECT 2,'Alaina','Jklxx'   Union all
SELECT 2,'Edward','Mnoqwww'
)
SELECT   SubjectID ,(STUFF((SELECT DISTINCT ', ' + CONCAT(CAST( StudentfName AS VARCHAR(50)), ',' ,CAST(StudentsName AS VARCHAR(50)))
        FROM cte i  WHERE i.SubjectID =u.SubjectID FOR XML PATH('')),1,1,'')) AS Studentfullname
From cte u
group by SubjectID

答案 3 :(得分:0)

这称为字符串聚合或Grouped连接。

有多种技巧。所有这些都在Aaron Bertrand的文章中有所描述,例如Grouped Concatenation in SQL Server

使用的最快和最简单的是创建和使用SQLCLR聚合。使用GROUPED_CONCAT_S作为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 PATH。 输入更容易,但不是那么容易使用。基本上,您将所有字段转换为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;

注意PATH, TYPE).value(...)功能。如果字段包含对'<&等具有特殊含义的字符,则会对其进行XML编码,例如&gt;,TYPE).value()会返回元素的值。

其他技术并未真正使用,因为它们更麻烦且速度更慢。