Assuming these are integer values, you can use a naked XML PATH
transform to handle group concatenation for you (and this even supports predictable and well-defined order, unlike all other group concatenation methods - which have undefined behavior).
DECLARE @t2 TABLE(ID INT);
DECLARE @t1 TABLE(ID INT IDENTITY(1,1),t2ID INT);
INSERT @t2(ID) VALUES(1),(2),(3);
INSERT @t1(t2ID) VALUES(1),(1),(1),(2);
SELECT t2.ID, t2IDs = STUFF((
SELECT ',' + CONVERT(VARCHAR(11), t1.ID)
FROM @t1 AS t1 WHERE t1.t2ID = t2.ID
ORDER BY t1.ID
FOR XML PATH('')),1,1,'')
FROM @t2 AS t2;
Results:
ID t2IDs
---- -----
1 1,2,3
2 4
3 NULL
Note that you don't need ID
in the GROUP BY
clause, because you're no longer needing to filter out duplicates matched by virtue of the JOIN
. Of course this assumes your column is named appropriately - if that column has duplicates with no JOIN
involved at all, then it has a terribly misleading name. A column named ID
should uniquely identify a row (but even better would be to call it what it is, and name it the same throughout the model, e.g. CustomerID
, OrderID
, PatientID
, etc).
If you're dealing with strings, you need to account for cases where the string may contain XML-unsafe characters (e.g. <
). In those cases, this is the method I've always used:
FOR XML PATH(''), TYPE).value(N'./text()[1]',N'nvarchar(max)'),1,1,'')