I need to write a sql query on the table such that the result would have the group by column along with the aggregated column with comma separators.
My table would be in the below format
|`````````|````````|
| ID | Value |
|_________|________|
| 1 | a |
|_________|________|
| 1 | b |
|_________|________|
| 2 | c |
|_________|________|
Expected result should be in the below format
|`````````|````````|
| ID | Value |
|_________|________|
| 1 | a,b |
|_________|________|
| 2 | c |
|_________|________|
You want to use FOR XML PATH
construct:
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
The STUFF
function is to get rid of the leading ', '
.
You can also see another examples here:
- SQL same unit between two tables needs order numbers in 1 cell
- SQL and Coldfusion left join tables getting duplicate results as a list in one column
Just for a balanced view, you can also do this with a CTE but its not as good as the cross apply method I don't think. I've coded this of the hoof so apologies if it doesn't work.
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