Skip to main content

How to create comma separated values in SQL server?

Comma Separated Values in SQL

Predominantly in reporting, you may gone through a situation where you need to convert a comma separated values into list of rows or to convert a list of rows into single column to display in a report. In this splash reading, you will understand the following:

  • How to convert comma separated data in a column to multiple rows
  • How to convert multiple rows into one comma separated values
  • Using COALESCE function
  • Using STUFF function

Convert comma separated data in a column to multiple rows

Here we have an Customer table with a list of products bought by each customer,

ID CUSTOMER PRODUCTS
1 Stuart Chain Saw,Circular Saw
2 Michael Drill,Hammer
3 Jonathan Sticky Notes,Mouse
4 Nabeel Mobile,Headset
Suppose you want to return this as a single table, list of products bought by each customer. we need to create a function that splits our comma separated columns into rows like you can see below,
CREATE FUNCTION [dbo].[SplitString]
(    
      @Input NVARCHAR(MAX),
      @Character CHAR(1)
)
RETURNS @Output TABLE (
      Item NVARCHAR(1000)
)
AS
BEGIN
      DECLARE @StartIndex INT, @EndIndex INT

      SET @StartIndex = 1
      IF SUBSTRING(@Input, LEN(@Input) - 1, LEN(@Input)) <> @Character
      BEGIN
            SET @Input = @Input + @Character
      END

      WHILE CHARINDEX(@Character, @Input) > 0
      BEGIN
            SET @EndIndex = CHARINDEX(@Character, @Input)
           
            INSERT INTO @Output(Item)
            SELECT SUBSTRING(@Input, @StartIndex, @EndIndex - 1)
           
            SET @Input = SUBSTRING(@Input, @EndIndex + 1, LEN(@Input))
      END

      RETURN
END
Now, we have created our function to split our columns we need to provide two inputs one is comma separated column values and other one is our separate string comma. This function identifies the comma using CHARINDEX and splits the values using SUBSTRING and inputs into a new row as an Item that will be returned in our select statement. Lets put this function into action,
How to use this function in a select statement?
select c.Id,c.CUSTOMER,o.Item as Product
    from CUSTOMERS c
    cross apply (select Item from SplitString(c.PRODUCTS,',') ) o
The above statement, retrieves the products based on customer using our SplitString function, the cross apply function used to join a table to a table-valued function is evoked for each row returned from the table. Lets see how the outputs will look like?
The T-SQL now has STRING_SPLIT()  function that makes this type of operation very easy. This function was first available in SQL Server 2016. There is no need to create our customized function like we created before we can simply replace that SplitString into STRING_SPLIT this might work it out. But this STRING_SPLIT has a compatibility level that you can see here in the Microsoft documentation. The syntax for using STRING_SPLIT() function is,
SELECT Id,CUSTOMER,value as Product
FROM CUSTOMERS  
    CROSS APPLY STRING_SPLIT(PRODUCTS, ',');
The returned output will look like this,

Convert multiple rows into one comma-separated values

To convert multiple rows into one comma-separated values, we can use two methods one is using COALESCE function and the other one is using the STUFF function. Suppose if we have products table like below,

Using COALESCE Function

The COALESCE function in SQL returns first the first non-NULL expression among its arguments.
DECLARE @prdlist VARCHAR(MAX)
SELECT @prdlist = COALESCE(@prdlist+', ' ,'') + Name
FROM Products
SELECT @prdlist
This statement returns the list of rows into a single comma-separated values like you see below,

Using STUFF Function

The STUFF function inserts a string into another string. It deletes a specified length of characters in the first string at the start position and then inserts the second string into the first string at the start position.
DECLARE @prdlist VARCHAR(MAX)
SET @prdlist =STUFF  
(  
    (  
      SELECT DISTINCT ', '+ CAST( P.NAME AS VARCHAR(MAX))  
      FROM Products P 
      FOR XMl PATH('')  
    ),1,1,''  
)
select @prdlist AS NAME
This statement returned output is as follows,
If you like to learn more about STUFF function, you can go through the Microsoft documentation here.



Comments

Nina Athena said…
Thank you for sharing this piece! It is very helpful and informative. Would like to see more updates from you.

Melbourne Web Developer
Prime Study Hub said…
Hi Nina Athena, Thanks for your valuable response. We will update our best.

Popular posts from this blog

FORCE ORDER in SQL Server

The FORCE ORDER is a query hint it executes the order of the tables exactly specified in a statement. When we use this query hint in a statement it will tell SQL server not to change the order of the joins in the query. Basically, the SQL server rearrange your joins to be in the order that it thinks it will be optimal for your query to execute. Now, Lets see the execution plan without the FORCE ORDER: The above execution plan demonstrates the optimal order of the joins returned by the SQL server. As you can see the order starts from the sales details and goes by bank details to employee details. Suppose if you don't want the SQL server to change the order of the joins in a query you can use FORCE ORDER to stop the default ordering. The syntax for FORCE ORDER query hint is, OPTION ( FORCE ORDER ); Now, Lets see the execution plan with the FORCE ORDER: select * from tbl_EmployeeDetails as e inner join tbl_BankDetails as b on e.Id=b.EmpID inner join tbl_S...

OPTION (MERGE JOIN) in SQL Server

OPTION (MERGE JOIN) in SQL Server The MERGE JOIN query hint is a best available join algorithm in SQL server. It is based on first sorting  both data sets according to the join conditions and then traversing through the sorted data sets and finding matches. The MERGE JOIN itself is very fast, but it can be an expensive choice if sort operations are required. This produces the best optimal execution plan. The syntax is, OPTION ( MERGE JOIN ); Now, Lets see how to use MERGE JOIN with SELECT statement.? select * from tbl_EmployeeDetails as e inner join tbl_BankDetails as b on b.EmpId=e.Id OPTION(MERGE JOIN); The statement returned optimal execution plan is, The MERGE JOIN operator gets a row from each input and compares them. In above statement, it merges all joins and first sorting data sets and then traversing through the sorted data sets and finding matches, if they are equal the rows are returned. If they are not equal, the lower-value row is rem...

How to manipulate JSON data in SQL server?

Manipulate JSON data in SQL Server JavaScript Object Notation (JSON) is a lightweight popular data exchangeable format used across modern IoT platforms, web and mobile applications etc. It is a language independent textual data format. JavaScript Object Notation (JSON) is also used for storing unstructured data in log files or NoSQL Databases such as Microsoft Azure Cosmos DB. Many RESTful web services that allow us to store and retrieve JSON formatted texts among different protocols using different Endpoints. The example of JSON text is as follows, [{         "customer":"Michael",         "products":["Watch","Mobile","Books"] }, {         "customer":"Stuart",         "products":["Laptop","Keyboard","Mouse"] } ] In this article you will understand the following, Read JSON data from table Modify JSON data in a table Validate JSON objects  ...

OPTION Loop Join in SQL Server

The OPTION ( LOOP JOIN ) would enforce LOOP JOIN across all joins in the query. Using the OPTION ( LOOP JOIN ) appears to allows the query optimizer to join the tables using the nested loops in which ever order SQL server decides it is optimal. The OPTION clause must be a last clause in a statement. The syntax is, OPTION ( LOOP JOIN ); Now, Lets see how to use LOOP JOIN with SELECT statement.? select *from tbl_EmployeeDetails as e inner join tbl_BankDetails as b on b.EmpID=e.Id inner join tbl_SalesDetails as s on s.BankId=b.Id OPTION(LOOP JOIN); The statement returned execution plan is, The above statement loops through all the joins that starts from sales details and goes by bank details to employee details in which the order that SQL server thinks it is optimal. This does not follow the order of joins that we specify. Suppose, if you want the SQL server to follow the order of joins that you specify you have to use FORCE ORDER in OPTION clause. Howe...