sqlsql-serverdatabase

Split a string with no delimiters into columns


I need to split a string in a column into one character each into it's own column in SQL Server 2012.

Example: if I have a column with 'ABCDE', I need to split it into 'A', 'B', 'C', 'D', 'E', with each of these into their own columns.

The length of the column to be split may vary, so I need this to be as dynamic as possible.

My question is different from the other post (Can Mysql Split a column?) since mine doesn't have any delimiters. Thanks


Solution

  • You can do this like this:

    DECLARE @t TABLE(id int, n VARCHAR(50))
    INSERT INTO @t VALUES
    (1, 'ABCDEF'),
    (2, 'EFGHIJKLMNOPQ')
    
    
    ;WITH cte AS
    (SELECT id, n, SUBSTRING(n, 1, 1) c, 1 AS ind FROM @t
     UNION ALL 
     SELECT id, n, SUBSTRING(n, ind + 1, 1), ind + 1 FROM cte WHERE LEN(n) > ind
    )
    
    SELECT *
    FROM cte 
    PIVOT (MAX(c) FOR ind IN([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[12],[13],[14],[15])) p
    

    Output:

    id  n               1   2   3   4   5   6   7    8    9    10   12   13   14    15
    1   ABCDEF          A   B   C   D   E   F   NULL NULL NULL NULL NULL NULL NULL  NULL
    2   EFGHIJKLMNOPQ   E   F   G   H   I   J   K    L    M    N    P    Q    NULL  NULL
    

    Here is dynamic version:

    DECLARE @l INT, @c VARCHAR(MAX) = ''
    SELECT @l = MAX(LEN(n)) FROM PivotTable
    
    WHILE @l > 0
    BEGIN
     SET @c = ',[' + CAST(@l AS VARCHAR(MAX)) + ']' + @c
     SET @l = @l - 1
    END
    
    SET @c = STUFF(@c, 1, 1,'')
    
    DECLARE @s NVARCHAR(MAX) = '
    ;WITH cte AS
    (SELECT id, n, SUBSTRING(n, 1, 1) c, 1 AS ind FROM PivotTable
     UNION ALL 
     SELECT id, n, SUBSTRING(n, ind + 1, 1), ind + 1 FROM cte WHERE LEN(n) > ind
    )
    
    SELECT *
    FROM cte 
    PIVOT (MAX(c) FOR ind IN(' + @c + ')) p'
    
    EXEC (@s)