The Standard SQL Server String Aggregation Solution
Prior to SQL Server 2017, Microsoft SQL Server lacked a native GROUP_CONCAT() function like MySQL or STRING_AGG() like PostgreSQL. Developers worldwide relied on FOR XML PATH('') combined with STUFF() to concatenate multiple row values into a single delimited string.
Anatomy of the STUFF + FOR XML PATH Query
- FOR XML PATH(''): Formats each row as XML elements with an empty tag wrapper, concatenating all values into a single stream.
- STUFF(string, 1, len, ''): Removes the leading comma or delimiter from the beginning of the concatenated string.
- .value('.', 'NVARCHAR(MAX)'): Converts the raw XML data back to an NVARCHAR string, unescaping XML entities like
&into&.
Frequently Asked Questions
When should I use STRING_AGG() instead?
If you are running SQL Server 2017 or later (or Azure SQL Database),
STRING_AGG(ColumnName, ', ') is cleaner and faster. For backwards compatibility with SQL Server 2008–2016, FOR XML PATH('') is mandatory.