good overview of several approaches:
http://blogs.msmvps.com/robfarley/2007/04/07/coalesce-is-not-the-answer-to-string-concatentation-in-t-sql/
Copy of article -
Coalesce is not a response to string concatenation in T-SQL. I have seen many reports over the years about using the COALESCE function to get string concatenation working in T-SQL. This is one example here (borrowed from Readifarian Marc Ridey).
DECLARE @categories varchar(200) SET @categories = NULL SELECT @categories = COALESCE(@categories + ',','') + Name FROM Production.ProductCategory SELECT @categories
This request can be very effective, but care must be taken to ensure that it is correctly understood, and the use of COALESCE. COALESCE is an ISNULL version that can take more than two parameters. It returns the first in the parameter list, which is not null. So this really has nothing to do with concatenation, and the following code snippet is exactly the same - without using COALESCE:
DECLARE @categories varchar(200) SET @categories = '' SELECT @categories = @categories + ',' + Name FROM Production.ProductCategory SELECT @categories
But the disordered nature of the databases makes this unreliable. The whole reason T-SQL does not yet have a concatenate function is because it is a collection for which a sequence of elements is important. Using this account assignment method for account assignment, you can actually find that the answer that is returned does not have all the values in it, especially if you want the substrings to be placed in a specific order. Consider the following, which on my machine returns "Accessories" when I wanted it to come back "," Bicycles, clothes, components, accessories ":
DECLARE @categories varchar(200) SET @categories = NULL SELECT @categories = COALESCE(@categories + ',','') + Name FROM Production.ProductCategory ORDER BY LEN(Name) SELECT @categories
It is much better to use a method that takes order into account and which was included in SQL2005 specifically for string concatenation - FOR XML PATH ('')
SELECT ',' + Name FROM Production.ProductCategory ORDER BY LEN(Name) FOR XML PATH('')
In a post I recently compared with GROUP BY and DISTINCT when using subqueries, I demonstrated the use of FOR XML PATH (''). Look at this and you will see how it works in the subquery. The "STUFF" function is available only to remove the leading comma.
USE tempdb; GO CREATE TABLE t1 (id INT, NAME VARCHAR(MAX)); INSERT t1 values (1,'Jamie'); INSERT t1 values (1,'Joe'); INSERT t1 values (1,'John'); INSERT t1 values (2,'Sai'); INSERT t1 values (2,'Sam'); GO select id, stuff(( select ',' + t.[name] from t1 t where t.id = t1.id order by t.[name] for xml path('') ),1,1,'') as name_csv from t1 group by id ;
FOR XML PATH is one of the only situations in which you can use ORDER BY in a subquery. The other is TOP. And when you use an unnamed column and FOR XML PATH (''), you will get direct concatenation without XML tags. This means that the strings will be encoded in HTML, so if you concatenate strings that may have <character (etc.), then you may later correct this, but in any case, this is the best way to concatenate strings in SQL Server 2005