动态分割字符串

时间:2019-04-26 10:22:42

标签: sql sql-server tsql

我的表格如下:

Column1   Column2        Column3
-----------------------------------
A         NULL           NULL
A]B       NULL           NULL
A]B]C     NULL           NULL

可能有数百万条这样的记录,我需要一个SQL查询以获取如下输出

Column1  Column2    Column3
-----------------------------
A        NULL       NULL
A        B          NULL
A        B          C

3 个答案:

答案 0 :(得分:0)

2步过程是 a)您需要创建一个功能为:

CREATE FUNCTION [dbo].[split]
(
    @string varchar(MAX),
    @delimiter CHAR(1),
    @pos INT 
)
RETURNS varchar(255)
AS
BEGIN
    DECLARE @start INT, @end INT, @count INT 
    SELECT @start = 1, @end = CHARINDEX(@delimiter, @string), @count = 1 
    WHILE @start < LEN(@string) + 1 BEGIN
        IF @end = 0 
            SET @end = LEN(@string) + 1 

        IF @count = @pos
            RETURN SUBSTRING(@string, @start, @end - @start)

        SET @start = @end + 1 
        SET @end = CHARINDEX(@delimiter, @string, @start)
        SET @count = @count + 1 

    END 
    RETURN '' -- not found
END

b)像这样获得所有3列的所有值

select isnull(dbo.split(cloumn1, ',', 0),'') as Column1,isnull(dbo.split(cloumn1, ',', 1),'') as Column2, isnull(dbo.split(cloumn1, ',', 2),'') as Column3 from <Table_Name>

答案 1 :(得分:0)

您可以尝试以下查询:

    --test data
    declare @tbl table (Col1 varchar(10), Col2 varchar(10), Col3 varchar(10));
    insert into @tbl values
    ('a',null,null),
    ('a]b',null,null),
    ('a]b]c',null,null);


    select case when firstIdx = 0 then col1 else substring(col1, 1, firstIdx - 1) end Col1,
           case when firstIdx = 0 
             then null 
             else case when secondIdx = 0 
               then substring(col1, firstIdx + 1, 100)
               else substring(col1, firstIdx + 1, secondIdx - firstIdx - 1) 
             end
           end Col2,
           case when secondIdx = 0 
             then null
             else substring(col1, secondIdx + 1, 100) 
           end Col3
    from (
        select Col1,
              charindex(']', Col1) firstIdx,
              charindex(']', Col1, charindex(']', Col1) + 1) secondIdx
        from @tbl
    ) a

答案 2 :(得分:-1)

您可以使用多个逗号分隔的CTE处理此问题。

以下查询具有两个CTE表t0t1。表t0使用']'函数提取第一个charindex的位置,类似地,t1用于提取下一个']'的位置。

使用case statementsubstring函数可以获得所需的输出。

with t0 as ( select Column1, Column2 ,  Column3, charindex(']',Column1) pos from #tbl),
     t1 as (select  Column1, Column2 ,  Column3, charindex(']',Column1,t0.pos+1) pos from t0)
select case when t0.pos = 0 then t0.column1 else substring(t0.Column1,0, t0.pos )  end Column1,
       case when t0.pos = 0 then null else substring(t0.Column1,t0.pos+1,case when t1.pos= 0 then len(t0.Column1)+1 else len(t0.Column1)- t1.pos end)end Column2,
       case when (t0.pos = 0 or(t0.pos <>0 and t1.pos =0)) then null else substring(t0.Column1,t1.pos+1, len(t0.Column1)+1 )   end Column3 
from t0
inner join t1 on t0.Column1 = t1.Column1  

输出

Column1 Column2 Column3
------- ------- -------
A       NULL    NULL
A       B       NULL
A       B       C