I have always discovered the lack of a built-in aggregate function that simply concatenates values using a specific custom separator, frustrating.
The closest thing I know is the XML hack:
select s.string as [text()]
from strings s
for xml path('')
But, in my opinion, a very strange way to do this, and you still have to handle the case with a trailing file or leading garbage. So, I thought I would write a CLR aggregate:
select dbo.Fold(s.string, ', ')
from strings s
So nice. Except that it doesn’t work very well when the number of rows reaches 5000. I really do not expect to run it against this data, but, to my surprise, aggregate performance deteriorates quite quickly as the data set grows. At first I did not understand why, I realized that the UDF problem in SQL Server is a problem.
I use UDF with a class StringBuilder, because of this I need to implement IBinarySerialize. But for reasons I don’t understand, SQL Server calls a Write / Read pair between each iteration Accumulate. Obviously, this creates a performance problem when the string gets large. Is there anyway to avoid this expensive serialization?
FYI, an XML hack is orders of magnitude faster.
source
share