2013-04-29 38 views
3

我刚刚在SQL Server上学习SQL。我需要将多行连接成一列。我查找了一些例子,但没有找到可以用来满足我需求的例子。将多行连接成一行

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 

我想连接的名称行,并与Inits上市 ''

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 

任何帮助,将不胜感激。非常感谢。

+0

我不能弄清当你想在逗号后的空间,当你不这样做。有什么区别? – RichardTheKiwi 2013-04-29 21:49:54

回答

3

要在SQL Server中执行此操作,您需要将字符串串联起来作为一个聚合函数。不幸的是,SQL Server没有group_concat()listagg()或一些相关的功能。下面是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; 

它看起来像你是不是名字比较分组,所以我包括了所有在距inits该行的字段。

+3

请**尝试**以**总是**检查您的工作并使用'FOR XML..TYPE'表格作为一般规则。没有足够智能的SQL Server连接的新手可能很难理解为什么他们得到'Msg 512,Level 16,State 1,Line 1:Subquery返回多于1个值'。还要注意,对于'','(2字符前缀),你需要使用STUFF关闭2个字符。 – RichardTheKiwi 2013-04-29 22:02:08

+0

@RichardTheKiwi。 。 。万分感谢。我离开计算机一个小时,意识到我在查询中犯了这两个错误(在stuff()中省略了'for xml path'和'2'。 – 2013-04-29 22:45:50

+0

非常感谢 – Mona 2013-05-01 20:22:35

6

不幸的是,SQL Server没有一个简单的函数来生成一个逗号分隔列表,你将不得不实现FOR XML PATH来获取列表。

有几个方法可以做到这一点,你可以使用STUFFFOR 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; 

SQL Fiddle with demo

或者你可以使用CROSS APPLYFOR 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); 

SQL Fiddle with Demo 。这些都产生的结果:

|  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 | 
+0

你这么多 – Mona 2013-05-01 20:21:39

+0

@Mona乐意帮忙! – Taryn 2013-05-01 20:22:58