16

我需要在表上编写一个sql查询,以便结果中包含group by列以及带有逗号分隔符的聚合列。SQL查询以便在SQL Server中按逗号分隔符分组以获得聚合结果

我的表将在下面的格式

|`````````|````````| 
    | ID | Value | 
    |_________|________| 
    | 1 | a | 
    |_________|________| 
    | 1 | b | 
    |_________|________| 
    | 2 | c | 
    |_________|________| 

预期的结果应该是在下面的格式

|`````````|````````| 
    | ID | Value | 
    |_________|________| 
    | 1 | a,b | 
    |_________|________| 
    | 2 | c | 
    |_________|________| 
+5

在MySQL中,你可以使用GROUP_CONCAT。有关如何在SQL Server中模拟该示例的示例,请参阅此问题:http://stackoverflow.com/questions/451415/simulating-group-concat-mysql-function-in-ms-sql-server-2005 – 2011-06-14 14:19:01

+0

+1正如@Eric Petroelje所说的,“交叉适用”。这是做到这一点的方法。 – 2011-06-14 14:23:19

回答

22

你想用FOR XML PATH结构:

select 
    ID, 
    stuff((select ', ' + Value 
      from YourTable t2 where t1.ID = t2.ID 
      for xml path('')), 
      1,2,'') [Values] 
from YourTable t1 
group by ID 

STUFF功能是摆脱领先', '的。

您还可以在这里看到另一个例子:

+0

+1为您的解决方案。同样,我们也可以使用交叉应用来完成。哪一种性能明智的最佳方式? – suryakiran 2011-06-15 03:00:34

+0

已接受答案,但需要执行该操作的最佳方式。 – suryakiran 2011-06-16 08:25:17

0

只是一个平衡的观点,你也可以用热膨胀系数,但它这样做不像我认为的交叉应用方法那么好。如果它不起作用,我已经编码了这个蹄。

WITH CommaDelimitedCTE (RowNumber,ID,[Value],[Values]) AS 
(
    SELECT 1,MT.ID , MIN(MT.Value), CAST(MIN(MT.Value) AS VARCHAR(8000)) 
    FROM MyTable MT 
    GROUP BY MT.ID 

    UNION ALL 

    SELECT CT.RowNumber + 1, MT.ID, MT.Value, CT.[Values] + ', ' + MT.Value 
    FROM MyTable MT 
    INNER JOIN CommaDelimitedCTE CT ON CT.ID = MT.ID 
    WHERE MT.[Value] > CT.[Value] 
) 

Select CommaDelimitedCTE.* from CommaDelimitedCTE 
    INNER JOIN (SELECT MT.ID,MAX(RowNumber) as MaxRowNumber from CommaDelimitedCTE GROUP BY MT.ID) Q on Q.MT.ID = CommaDelimitedCTE.MT.ID 
    AND Q.MaxRowNumber = CommaDelimitedCTE.RowNumber