Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comma-separated String into Table's Column in SQL Server

I am working with SQL Server, I have successfully converted a table's rows into comma-separated values, now I want to convert that string of comma-separated values back to table's rows.

I have this string (Varchar)

DECLARE @str AS varchar(Max)
SET @str = '0.00,0.00,1576.95,0.00,4105.88,1017.87,0.00,6700.70'

I want these values into rows.

Like

0.00
0.00
1576
...
like image 705
DareDevil Avatar asked Oct 20 '25 13:10

DareDevil


2 Answers

This question is a duplicate of a few others, but some of the accepted answers are still the inefficient WHILE loops or recursive CTEs. There are three ways to accomplish a split that won't kill performance:

  • Numbers / Tally Table: http://www.sqlservercentral.com/articles/Tally+Table/72993/ (free registration required)

  • XML: https://www.simple-talk.com/blogs/2012/01/05/using-xml-to-pass-lists-as-parameters-in-sql-server/

  • SQLCLR: there are numerous examples of this on many sites but your best (and easiest) bet is to either grab the one provided in the Numbers / Tally Table article noted above OR just install SQL# (SQLsharp) (I am the author of SQL# but String_Split and String_Split4k are in the Free version).

like image 177
Solomon Rutzky Avatar answered Oct 23 '25 05:10

Solomon Rutzky


Create a function:

CREATE FUNCTION [dbo].[Split](@String nvarchar(4000), @Delimiter char(1))
RETURNS @Results TABLE (Items nvarchar(4000))
AS
BEGIN
    DECLARE @Index INT
    DECLARE @Slice nvarchar(4000)
    -- HAVE TO SET TO 1 SO IT DOESN’T EQUAL ZERO FIRST TIME IN LOOP
    SELECT @Index = 1
    WHILE @Index !=0
        BEGIN
            SELECT @Index = CHARINDEX(@Delimiter,@String) --Getting the indexof the first Occurrence of the delimiter

            -- Saving everything to the left of the delimiter to the variable SLICE
            IF @Index !=0
                SELECT @Slice = LEFT(@String,@Index - 1)
            ELSE
                SELECT @Slice = @String

            -- Inserting the value of Slice into the Results SET
            INSERT INTO @Results(Items) VALUES(@Slice)

            --Remove the Slice value from Main String
            SELECT @String = RIGHT(@String,LEN(@String) - @Index)

            -- Break if Main String is empty
            IF LEN(@String) = 0 BREAK
        END
    RETURN
END

Pass the string @str and the delimiter (,) to the function.

SELECT Items FROM [dbo].[Split] (@str, ',')

It will return the result as a table:

Items

0.00
0.00
1576.95
0.00
4105.88
1017.87
0.00
6700.70

See SQL Fiddle

like image 40
Raging Bull Avatar answered Oct 23 '25 05:10

Raging Bull