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