This article will cover the STRING_SPLIT function in SQL Server including an overview and detailed usage examples.
SQL Server users usually need string parsing and manipulation functions. In several scenarios, this string parsing or manipulation operation can be very painful for developers or database administrators. For this reason, in every SQL Server version, Microsoft has announced new string functions. New string functions like STRING_ESCAPE, STRING_SPLIT were added into SQL Server 2016 and CONCAT_WS, STRING_AGG, TRANSLATE, TRIM string functions were added into SQL Server 2017.
In this article, we will discuss the STRING_SPLIT function, in particular. The purpose of this built-in string function is to convert string arrays to columns which are separated by any separator. The below figure illustrates the main idea of this function.
Image may be NSFW.
Clik here to view.

As we already noted in the entry section of the article, this function was introduced in SQL Server 2016 and the previous versions of SQL Server do not support this built-in function. In other words, this function does not support under the 130 compatibility level. The following table illustrates the versions of SQL Server and their compatibility levels.
SQL Server Versions Compatibility LevelSQL Server 2019 preview
150
SQL Server 2017 (14.x)
140
SQL Server 2016 (13.x)
130
SQL Server 2014 (12.x)
120
SQL Server 2012 (11.x)
110
SQL Server 2008 R2
100
SQL Server 2008
100
SQL Server 2005 (9.x)
90
SQL Server 2000
80
Now, let’s start to discuss usage concepts and other details of this function.
Syntax:The syntax is very simple as this table valued built-in function takes only two parameters. First one is a string and the second one is a single character.
STRING_SPLIT (string, separator)The following sample shows simplest usage of this function.
select value from STRING_SPLIT('apple,banana,lemon,kiwi,orange,coconut',',')Image may be NSFW.
Clik here to view.

The following SELECT query will return an error because of the database compatibility level.
ALTER DATABASE AdventureWorks2012 SET compatibility_LEVEL=120 GO select value from STRING_SPLIT('apple , banana , lemon , kiwi , orange ,coconut',',')Image may be NSFW.
Clik here to view.

The reason for this error is that we decreased the database compatibility level under the 130 and SQL Server returns an error. Keep in mind, that if you are planning to use this function in your customer environment you have to be sure about their database compatibility level.
STRING_SPLIT and WHERE clause:Through the WHERE clause, we can filter the result set of the STRING_SPLIT function. In the following select statement, the WHERE clause will filter the result set of the function and will only return the row or rows which start with “le”
select value from STRING_SPLIT('apple,banana,lemon,kiwi,orange,coconut',',') WHERE value LIKE 'le%'Image may be NSFW.
Clik here to view.

Also, we can use the function in this form:
USE AdventureWorks2014 GO select * from HumanResources.Employee WHERE [jobtitle] IN (select value from string_split('Chief Executive Officer , Design Engineer',','))Image may be NSFW.
Clik here to view.

Now, we will look at the execution plan with help of ApexSQL Plan . We can see the Table valued function operator in the execution plan.
Image may be NSFW.
Clik here to view.

When we hover over the table-valued function operator in the execution plan, we can find out all the details about this operator. Under the object label, the STRING_SPLIT function can be seen. These all details tell us that this function is a table-valued function.
Image may be NSFW.
Clik here to view.

STRING_SPLIT and ORDER BY
Another requirement which we need in the SELECT statements is sorting functionality. We can sort the output of this function which looks like the other T-SQL statements.
select value from STRING_SPLIT('apple,banana,lemon,kiwi,orange,coconut',',') order by valueImage may be NSFW.
Clik here to view.

Note : When I reviewed some customer feedback about SQL Server, I came across a suggestion about the STRING_SPLIT function which is “The new string splitter function in SQL Server 2016 is a good addition but it needs an extra column, a ListOrder column which denotes the order of the split values.” In my thought, this feature can be very useful for this function and I voted for this suggestion.
STRING_SPLIT and JOIN:We can combine the function result set to the other table with the JOIN clause.
USE [AdventureWorks2014] GO SELECT [PersonType] ,[NameStyle] ,[FirstName] ,[MiddleName] ,[LastName] FROM [Person].[Person] P INNER JOIN string_split('Ken,Terri,Gail',',') on P.FirstName=valueImage may be NSFW.
Clik here to view.

Also, we can use CROSS APPLY function to combine the STRING_SPLIT function result set with other tables. CROSS APPLY function provides us to join table value function output to other tables.
In the following sample, we will create two tables and first table (#Countries) stores name and the continent of countries and second table (#CityList) stores city of countries table but the crucial point is #CityList table stores the city names as a string array which is separated by a comma. We will join this to the table over country columns and use the CROSS APPLY function to transform city array into a column. The below image can illustrate what will we do.Image may be NSFW.
Clik here to view.

DROP TABLE IF EXISTS #Countries GO DROP TABLE IF EXISTS #CityList GO CREATE TABLE #Countries (Continent VARCHAR(100), Country VARCHAR(100)) GO CREATE TABLE #CityList (Country VARCHAR(100), City VARCHAR(5000)) GO INSERT INTO#Countries VALUES('Europe','France'),('Europe','Germany') INSERT INTO #CityList VALUES('France','Paris,Marsilya,Lyon,Lille,Nice'), ('Germany','Berlin,Hamburg,Munih,Frankfurt,Koln') SELECT CN.Continent,CN.Country,value FROM #CityList CL CROSS APPLY string_split(CL.City,',')INNER JOIN #Countries CN ONCL.Country = CN.Country DROP TABLE IF EXISTS #Countries GO DROP TABLE IF EXISTS #CityList GO
Image may be NSFW.
Clik here to view.

More details about STRING_SPLIT After all the basic usage methodology of this function; we will delve into more detail. In the previous examples we always used a comma (,) as a separator fo