T-SQL String DeAggregate (Split, Ungroup) in SQL Server

A while back I posted a simple way to aggregate strings in SQL Server, but what if your task is opposite – you have a character-separated string values in your fields and you need to slice them into separate rows? Consider following scenario, you have a table:

CREATE TABLE #Employees (Country varchar(50), FirstNames varchar(50))

INSERT INTO #Employees(Country,FirstNames) 
	 VALUES ('UK','Anne,Michael,Robert,Steven')
INSERT INTO #Employees(Country,FirstNames)
     VALUES ('USA','Andrew,Janet,Laura,Margaret,Nancy')

SELECT Country, FirstNames FROM #Employees

That looks like this

Country  FirstNames
UK       Anne,Michael,Robert,Steven
USA      Andrew,Janet,Laura,Margaret,Nancy

and now you need to split FirstNames so that every FirstName is displayed on separate row.
First we need a function to split strings. There’re plenty solutions, for example you can use one found by Cade Roux @ StackOverflow:

CREATE FUNCTION dbo.Split (@sep char(1), @s varchar(512))
RETURNS table
AS
RETURN (
    WITH Pieces(pn, start, stop) AS (
      SELECT 1, 1, CHARINDEX(@sep, @s)
      UNION ALL
      SELECT pn + 1, stop + 1, CHARINDEX(@sep, @s, stop + 1)
      FROM Pieces
      WHERE stop > 0
    )
    SELECT pn,
      SUBSTRING(@s, start, CASE WHEN stop > 0 THEN stop-start ELSE 512 END) AS s
    FROM Pieces
  )

Once we have it, it’s only a matter of joining function results with remaining fields from the original table (Note CROSS APPLY statement – it will connect all split values to the original row):

SELECT Country, S as FirstName FROM #Employees CROSS APPLY Split(',', FirstNames)

The result is

Country FirstName
UK      Anne
UK      Michael
UK      Robert
UK      Steven
USA     Andrew
USA     Janet
USA     Laura
USA     Margaret
USA     Nancy

Leave a Reply

Your email address will not be published. Required fields are marked *