SQL Server:如何使用2个分隔符将字符串拆分为列和行?

时间:2016-03-11 10:51:51

标签: sql-server matrix split

输入:string = '1,2,3|4,5|7,8,9,10'

结果:

----------------------------
|col1 | col2 | col3 | col4 |
----------------------------
|   1 |    2 |    3 |  null|
|   4 |    5 | null |  null|
|   7 |    8 |    9 |    10|
--------------------------- 

我知道如何拆分行,但是如何拆分成多列。

1 个答案:

答案 0 :(得分:2)

-- SELECT * FROM [dbo].[SplitMatrix] ('1,12,-3,test ;4, 5,6;', ',', ';')
CREATE FUNCTION [dbo].[SplitMatrix] (   
    @String NVARCHAR(MAX),
    @SepColumn NCHAR(1),
    @SepRow NCHAR(1)
)

RETURNS @Matrix TABLE (
     [1] NVARCHAR(MAX)
    ,[2] NVARCHAR(MAX)
    ,[3] NVARCHAR(MAX)
    ,[4] NVARCHAR(MAX)
    ,[5] NVARCHAR(MAX)
    ,[6] NVARCHAR(MAX)
    ,[7] NVARCHAR(MAX)
    ,[8] NVARCHAR(MAX)
    ,[9] NVARCHAR(MAX)
    ,[10] NVARCHAR(MAX)
)

AS
BEGIN

    ;WITH rows_n (rn, n1, n2 ) AS ( 
    SELECT CAST(1 as int) as rn, CAST(0 as bigint) as n1, CHARINDEX(@SepRow, @String+@SepRow) as n2
    UNION ALL 
    SELECT rn + 1, n2 as n1, CHARINDEX(@SepRow, @String+@SepRow, n2+1) as n2
    FROM rows_n
    WHERE n2 < LEN(@String)
    )
    , col_n (n1, n2 ) AS ( 
    SELECT CAST(0 as bigint) as n1, CHARINDEX(@SepColumn, REPLACE(@String,@SepRow,@SepColumn) + @SepColumn) as n2
    UNION ALL 
    SELECT n2 as n1, CHARINDEX(@SepColumn, REPLACE(@String,@SepRow,@SepColumn) + @SepColumn, n2+1) as n2
    FROM col_n
    WHERE n2 < LEN(@String)
    )

    INSERT INTO @Matrix
    SELECT [1],[2],[3],[4],[5],[6],[7],[8],[9],[10]--,rn
    FROM 
        (SELECT
            ROW_NUMBER() OVER(PARTITION BY rn ORDER BY col_n.n1) as cn
            ,SUBSTRING(@String, col_n.n1+1, col_n.n2 - col_n.n1 - 1) as val
            ,rows_n.rn
        FROM rows_n
            LEFT JOIN col_n ON  col_n.n1 >= rows_n.n1 AND col_n.n1 < rows_n.n2) matrix
    PIVOT (
        MIN(val) FOR cn IN ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10]) 
    ) pvt
    OPTION (MAXRECURSION 0);

    RETURN;

END
GO