2011-03-30 23:03:11 8 Comments
I have a SQL Table like this:
| SomeID | OtherID | Data
+----------------+-------------+-------------------
| abcdef-..... | cdef123-... | 18,20,22
| abcdef-..... | 4554a24-... | 17,19
| 987654-..... | 12324a2-... | 13,19,20
is there a query where I can perform a query like SELECT OtherID, SplitData WHERE SomeID = 'abcdef-.......'
that returns individual rows, like this:
| OtherID | SplitData
+-------------+-------------------
| cdef123-... | 18
| cdef123-... | 20
| cdef123-... | 22
| 4554a24-... | 17
| 4554a24-... | 19
Basically split my data at the comma into individual rows?
I am aware that storing a comma-separated
string into a relational database sounds dumb, but the normal use case in the consumer application makes that really helpful.
I don't want to do the split in the application as I need paging, so I wanted to explore options before refactoring the whole app.
It's SQL Server 2008
(non-R2).
Related Questions
Sponsored Content
42 Answered Questions
[SOLVED] How do I split a string so I can access item x?
- 2008-08-05 18:15:47
- GateKiller
- 792680 View
- 460 Score
- 42 Answer
- Tags: sql sql-server tsql split
44 Answered Questions
[SOLVED] How to concatenate text from multiple rows into a single text string in SQL server?
- 2008-10-11 23:49:59
- JohnnyM
- 1951680 View
- 1631 Score
- 44 Answer
- Tags: sql sql-server csv string-concatenation group-concat
76 Answered Questions
12 Answered Questions
[SOLVED] Best way to get identity of inserted row?
- 2008-09-03 21:32:02
- Oded
- 716919 View
- 947 Score
- 12 Answer
- Tags: sql sql-server tsql
4 Answered Questions
[SOLVED] Inserting multiple rows in a single SQL query?
- 2009-01-17 05:55:54
- rits
- 2326716 View
- 1478 Score
- 4 Answer
- Tags: sql sql-server tsql insert
23 Answered Questions
[SOLVED] How to convert comma-separated String to ArrayList?
- 2011-09-20 16:40:02
- Jame
- 754444 View
- 457 Score
- 23 Answer
- Tags: java string collections split
37 Answered Questions
[SOLVED] How can I remove duplicate rows?
- 2008-08-20 21:51:29
- Seibar
- 1084231 View
- 1193 Score
- 37 Answer
- Tags: sql-server tsql duplicates
19 Answered Questions
[SOLVED] What is the best way to auto-generate INSERT statements for a SQL Server table?
- 2009-06-11 17:42:28
- JosephStyons
- 399154 View
- 515 Score
- 19 Answer
- Tags: sql-server ssms code-generation
1 Answered Questions
[SOLVED] Turning related Comma Separated strings into individual rows with multiple columns
- 2017-08-24 12:47:12
- dmonder
- 162 View
- 2 Score
- 1 Answer
- Tags: sql-server sql-server-2016
3 Answered Questions
Turning string into rows
- 2015-07-02 10:48:01
- CB Du Rietz
- 194 View
- 0 Score
- 3 Answer
- Tags: sql-server tsql
14 comments
@Spider 2019-02-13 07:18:37
You can use the following function to extract data
@Dungeon 2019-01-07 06:27:09
Very late but try this out:
So we were having this: tbl_Sample :
After running this query:
Thanks!
@Jag Kandasamy 2018-08-22 02:56:26
Please refer below TSQL. STRING_SPLIT function is available only under compatibility level 130 and above.
TSQL:
RESULT:
Colour
red blue green yellow black
@RichardTheKiwi 2011-03-30 23:18:05
You can use the wonderful recursive functions from SQL Server:
Sample table:
The query
Output
@Aliostad 2011-03-30 23:20:09
+1 That is my answer but with query itself as well!
@ca9163d9 2012-02-21 23:58:11
The code doesn't work if change the data type of the column
Data
fromvarchar(max)
tovarchar(4000)
, e.g.create table Testdata(SomeID int, OtherID int, Data varchar(4000))
?@RichardTheKiwi 2012-02-22 08:35:36
@NickW this may be because the parts before and after UNION ALL return different types from the LEFT function. Personally I don't see why you wouldn't jump to MAX once you get to 4000...
@Jagadeesh G 2013-07-27 05:59:47
@RichardTheKiwi this example is very useful for me thanks
@dsz 2014-01-14 05:19:00
For a BIG set of values, this can overrun the recursion limits for CTEs.
@RichardTheKiwi 2014-01-14 20:50:51
@dsz That's when you use
OPTION (maxrecursion 0)
@RubyHaus 2015-03-20 14:04:48
@RichardTheKiwi - this is perfect, exactly what I needed. Impressive solution!
@Daniel 2015-07-09 06:29:39
@RichardTheKiwi - legend!
@smoore4 2016-07-15 15:27:39
The LEFT functions may need a CAST to work....for example LEFT(CAST(Data AS VARCHAR(MAX))....
@Andrew Steitz 2017-05-03 17:22:45
Wish I could upvote more than once!
@John 2017-08-08 16:23:37
Can i use this result as value of IN() ?
@RichardTheKiwi 2017-08-10 23:14:09
@Fawel Describe what you actually need and what you are starting from in a new question. Someone will answer more contextually
@John 2017-08-11 01:01:32
select * from t1 where IN(comma separated value from another table). can I use comma separated result into IN?
@mr R 2018-01-31 13:22:01
Function
Use case
Or just a select with multiple result set
@Arun Pratap Singh 2017-10-06 10:21:00
Below works on sql server 2008
Will get all Cartesian product with the origin table columns plus "items" of split table.
@Pரதீப் 2016-03-30 10:01:30
Finally, the wait is over with SQL Server 2016. They have introduced the Split string function,
STRING_SPLIT
:All the other methods to split string like XML, Tally table, while loop, etc.. have been blown away by this
STRING_SPLIT
function.Here is an excellent article with performance comparison: Performance Surprises and Assumptions: STRING_SPLIT.
For older versions, using tally table here is one split string function(best possible approach)
Referred from Tally OH! An Improved SQL 8K “CSV Splitter” Function
@Syed Md. Kamruzzaman 2017-03-06 06:21:49
very important answer
@Stewart 2017-04-28 16:12:16
I would use STRING_SPLIT if only the server were on SQL Server 2016! BTW according to the page you've linked to, the field name it outputs is
value
, notSplitData
.@dsz 2014-01-14 06:20:01
As of Feb 2016 - see the TALLY Table Example - very likely to outperform my TVF below, from Feb 2014. Keeping original post below for posterity:
Too much repeated code for my liking in the above examples. And I dislike the performance of CTEs and XML. Also, an explicit
Id
so that consumers that are order specific can specify anORDER BY
clause.@Eske Rahn 2016-04-02 01:57:17
Nice to see that it have been solved in the 2016 version, but for all of those that is not on that, here are two generalized and simplified versions of the methods above.
The XML-method is shorter, but of course requires the string to allow for the xml-trick (no 'bad' chars.)
XML-Method:
Recursive method:
Function in action
XML-METHOD 2: Unicode Friendly 😀 (Addition courtesy of Max Hodges)
create function dbo.splitString(@input nVarchar(max), @Splitter nVarchar(99)) returns table as Return SELECT Split.a.value('.', 'NVARCHAR(max)') AS Data FROM ( SELECT CAST ('<M>' + REPLACE(@input, @Splitter, '</M><M>') + '</M>' AS XML) AS Data ) AS A CROSS APPLY Data.nodes ('/M') AS Split(a);
@jpaugh 2016-08-31 21:26:52
This may seem obvious, but how do you use these two functions? Especially, can you show how to use it in the OP's use case?
@Eske Rahn 2016-09-09 12:50:53
Here is a quick example: Create table TEST_X (A int, CSV Varchar(100)); Insert into test_x select 1, 'A,B'; Insert into test_x select 2, 'C,D'; Select A,data from TEST_X x cross apply dbo.splitString(x.CSV,',') Y; Drop table TEST_X
@Nitin Badole 2019-01-18 10:30:47
This is exactly what I needed! Thank you.
@tommylux 2015-03-16 16:40:25
I always use the XML method. Make sure you use VALID XML. I have two functions to convert between valid XML and Text. (I tend to strip out the carriage returns as I don't usually need them.
@Stewart 2017-05-01 09:30:48
There's a small problem with the code you've got there. It'll change '<' to '&lt;' instead of '<' like it should. So you need to encode '&' first.
@Shnugo 2018-07-19 09:02:10
There's no need for such a function... Just use the implicit abilities. Try this out:
SELECT (SELECT '<&> blah' + CHAR(13)+CHAR(10) + 'next line' FOR XML PATH(''))
@user3245135 2014-01-28 15:29:45
@tobriand 2015-11-03 13:45:55
Does exactly what I was after, and easier to read than many of the other examples (provided there's already a function in the DB for delimited string split). As someone not previously familiar with
CROSS APPLY
, that's kinda useful!@Jayendran 2017-06-07 15:29:53
I couldn't understand this part (select Code from dbo.Split(t.Data,',') ) ? dbo.Split is an table where is this exist and also Code is the Column in Split table ? i couldn't find the list of those table or values in anywhere in this Page ?
@Akbar Kautsar 2017-08-11 04:07:38
My working code are:
select t.OtherID, x.* from testData t cross apply (select item as Data from dbo.Split(t.Data,',') ) x
@Jayvee 2013-11-07 13:22:44
@Aaron Schultz 2017-10-16 20:06:19
This is one of the few methods that works with the limited SQL support in Azure SQL Data Warehouse.
@bvr 2013-04-18 12:33:11
Check this
@user1151923 2015-03-04 18:22:22
When using this approach you have to make sure that none of your values contains something that would be illegal XML
@Control 2015-07-08 16:46:48
This is great. Can I ask you, how would I rewrite that if I wanted the new column to only show the first character from my split string?
@chazbot7 2017-01-06 00:46:47
This worked perfectly, thank you! I had to update the VARCHAR limit but it worked perf after that.
@Chris Brickhouse 2018-04-08 19:20:25
this worked perfectly for sql 2014. thanks!
@Klix Media 2012-07-28 12:58:24
with only tiny little modification to above query...
@Leigh 2012-07-28 20:50:43
Can you briefly explain how this is an improvement over the version in the accepted answer?
@TamusJRoyce 2015-01-05 16:24:40
No union all...less code. Since it is using union all instead of union, shouldn't be a performance difference?
@Oedhel Setren 2015-02-27 15:20:30
This didn't return all the rows it should have. I'm not sure what about the data requires the union all, but your solution returned the same number of rows as the original table.
@Eske Rahn 2016-04-07 22:38:21
(the problem here is that the recursive part is the one omitted...)