SQL Server: Concatenate Multiple Rows Into Single String

I came across a situation where I have to concatenate multiple rows (a column) into single string of text for reporting purpose. There are multiple ways to concatenate rows into string. Now we will see a couple of the easiest techniques here.

1. Concatenate Multiple Rows Using FOR XML PATH

The simplest and straight forward way to concatenate rows into a string value is to use FOR XML PATH in a select query. This FOR XML PATH method can be used in SQL Server version 2005 and higher.

In the below sample query, I’ve concatenated multiple rows of the column “CountryName” to a single string and added a comma between the country names. Then using a substring function, I’m removing the leading comma.

select CountryName from Application.Countries

Select SUBSTRING(
(
	SELECT ',' + CountryName AS 'data()'
		FROM Application.Countries 
		FOR XML PATH('')
), 2 , 9999) As Countries

SQL Server Concatenate Multiple Rows into String 01

2. Concatenate Rows Using COALESCE

You can concatenate rows into single string using COALESCE method. This COALESCE method can be used in SQL Server version 2008 and higher. All you have to do is, declare a varchar variable and inside the coalesce, concat the variable with comma and the column, then assign the COALESCE to the variable.

In this method, you don’t need to worry about the trailing comma. You may need a stored procedure or a function to do this operation and get the concatenated string value.

Select CountryName from Application.Countries

Declare @val Varchar(MAX);
Select @val = COALESCE(@val + ', ' + CountryName, CountryName) From Application.Countries
Select @val;

SQL Server Concatenate Multiple Rows into String

3. Using STRING_AGG

The STRING_AGG is a string function which will simplify the concatenation of rows. STRING_AGG is designed for this purpose. Unfortunately it will be available in the feature release of SQL Server. This new function is available from SQL Server 2017 onwards. The syntax for using STRING_AGG is as below. Read more about using STRING_AGG here.

SELECT STRING_AGG( ISNULL(CountryName, ' '), ',') As Countries From Application.Countries

Reference

  • Documentation of COALESCE at msdn.
  • Documentation of STRING_AGG at msdn.

Related Articles & Tools

4 comments for “SQL Server: Concatenate Multiple Rows Into Single String

  1. Cristinel Boboc
    Feb 20, 2018 at 1:22 pm

    Here is another idea about how you can achieve the same using recursive CTE. Is very flexible and can be enhanced thoroughly, but I want to show only the proof of concept

    DECLARE @t TABLE(id INT PRIMARY KEY, val VARCHAR(MAX), categ INT)

    INSERT INTO @t VALUES
    (1, ‘abc’, 1),
    (2, ‘def’, 1),
    (3, ‘ghi’, 1),
    (4, ‘xyz’, 2),
    (5, ‘stu’, 2),
    (6, ‘prq’, 2);

    WITH a AS
    (SELECT row_number() OVER (PARTITION BY categ ORDER BY id ASC) rn_a,
    row_number() OVER (PARTITION BY categ ORDER BY id DESC) rn_d,
    id,
    CAST(val AS VARCHAR(MAX)) val,
    categ,
    @@ROWCOUNT rn_c
    FROM @t
    ),
    b AS
    (SELECT * FROM a WHERE rn_a = 1
    UNION ALL
    SELECT a.rn_a, a.rn_d, b.id, CAST(CONCAT(b.val, ‘ ‘, a.val) AS VARCHAR(MAX)), b.categ, @@ROWCOUNT rn_c
    FROM a JOIN b ON a.rn_a = b.rn_a + 1 AND a.categ = b.categ
    )
    SELECT * FROM b WHERE rn_d = 1

    • Feb 20, 2018 at 8:57 pm

      Hi Cristinel Boboc,
      Good Idea. It works great and it’s flexible. Thank you for sharing.

  2. Jo
    Dec 18, 2017 at 2:42 pm

    Hi, this is great. My doubt would be, what if we would like to have some 2 columns grouped? Say on this example, you would have another column with the continent and then the xml string with the countries within that group, can that be done using this function?
    Thanks

Leave your thoughts...