Concatenate multiple rows into one row

匿名 (未验证) 提交于 2019-12-03 08:56:10

问题:

I am just now learning SQL on SQL Server. I need to concatenate multiple rows into one column. I have looked for examples, but do not find one that I can use to suit my needs.

Country     ProjectTA   Complexity TID  Sites   Inits   Name United States A8022 Obesity Low  4692   69  JT  AD United States A8022 Obesity Low  4692   69  jpni    CBM Budget United States A8022 Obesity Low  4692   69  PIHR    AD United States A8022 Obesity Low  4692   69  jpni    CBM Budget United States A8022 Obesity Low  4692   69  hale    ePublishing Group United States S8033 CNS Medium   5423   69  ShyP    CBM Payment United States S8033 CNS Medium   5423   69  dedu    ePublishing Group United States S8033 CNS Low  5423   69  AHrp    ePublishing Group 

I want to concatenate rows by Name and have Inits listed with ','

United States A8022 Obesity Low 4692    69 JT,PIHR  AD United States A8022 Obesity Low 4692    69 jpni, PIHR   CBM Budget United States A8022 Obesity Low 4692    69 hale          ePublishing Group United States S8033 CNS Medium  5423    69 ShyP          CBM Payment United States S8033 CNS Medium  5423    69 dedu, Ahrp   ePublishing Group 

Any help would be appreciated. Thanks so much.

回答1:

Unfortunately SQL Server does not have an easy function to generate a comma separated list, you will have to implement FOR XML PATH to get the list.

There are a few ways to do this, you can use STUFF and FOR XML PATH:

select distinct t1.country,   t1.ProjectTA,    t1.Complexity,   t1.TID,   t1.Sites,   STUFF(          (SELECT ', ' + t2.Inits           FROM yt t2           where t1.Country = t2.Country             and t1.ProjectTA = t2.ProjectTA             and t1.TID = t2.TID             and t1.Sites = t2.Sites             and t1.name = t2.name           FOR XML PATH (''))           , 1, 1, '')  AS inits,   t1.name from yt t1; 

See SQL Fiddle with demo

Or you can use CROSS APPLY and FOR XML PATH:

select distinct t1.country,   t1.ProjectTA,    t1.Complexity,   t1.TID,   t1.Sites,    left(t2.inits, len(t2.inits)-1) inits,   t1.name from yt t1 cross apply (   select t2.Inits + ', '   from yt t2   where t1.Country = t2.Country     and t1.ProjectTA = t2.ProjectTA     and t1.TID = t2.TID     and t1.Sites = t2.Sites     and t1.name = t2.name   FOR XML PATH('') ) t2 (inits); 

See SQL Fiddle with Demo. These both yield the result:

|       COUNTRY | PROJECTTA |  COMPLEXITY |  TID | SITES |      INITS |              NAME | ------------------------------------------------------------------------------------------- | United States |     A8022 | Obesity Low | 4692 |    69 |       hale | ePublishing Group | | United States |     A8022 | Obesity Low | 4692 |    69 | jpni, jpni |        CBM Budget | | United States |     A8022 | Obesity Low | 4692 |    69 |   JT, PIHR |                AD | | United States |     S8033 |     CNS Low | 5423 |    69 | dedu, AHrp | ePublishing Group | | United States |     S8033 |  CNS Medium | 5423 |    69 | dedu, AHrp | ePublishing Group | | United States |     S8033 |  CNS Medium | 5423 |    69 |       ShyP |       CBM Payment | 


回答2:

To do this in SQL Server, you need to do concatenate the strings together as an aggregatino function. Unfortunately, SQL Server does not have group_concat() or listagg() or some related function. Here is the method in SQL Server:

select Country, ProjectTA, Complexity, TID,        stuff((select ', '+Inits               from t t2               where t2.Name = t.Name and                     t2.country = t.country and                     t2.ProjectTA = t.ProjectTA and                     t2.Tid = t.Tid               for xml path(''), type              ).value('.','nvarchar(max)'), 1, 2, ''             ) as InitsList,        Name from t group by country, ProjectTA, Complexity, TID, name; 

It looks like you are grouping by more than name, so I included all of the fields on the row apart from inits.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!