SQL Server 2012通过分隔符将字符串分为三列

时间:2015-01-02 17:04:15

标签: sql sql-server string

无法用多个分隔符划分下面的字符串

示例数据

            column1
row1   'ABC>DEF>GHI'
row2   'ABC>DEF>GHI'
row3   'ABC>DEF'
row4   'ABC>DEF'
row5   'ABC>DEF>GHI'

目标

      col1  col2  col3
row1  'ABC' 'DEF' 'GHI'
row2  'ABC' 'DEF' 'GHI'
row3  'ABC' 'DEF'
row4  'ABC' 'DEF'
row5  'ABC' 'DEF' 'GHI'

我想在每个>

之前和之后将这一行分成3列

我管理了这两个案例陈述,这些陈述在第一个分隔符之前和最后一个分隔符之后捕获,但是我在两个分隔符之间陷入了捕获。

CASE 
   WHEN Indicator LIKE '%>%' 
     THEN LEFT (column1, Charindex('>' , column1) - 1) 
     ELSE col1 
END as col1

CASE 
   WHEN Indicator LIKE '%>%' 
      THEN RIGHT (column1, Charindex('>' , Reverse(column1)) - 1) 
END as col3

非常感谢任何帮助

由于

2 个答案:

答案 0 :(得分:3)

使用Parsename功能技巧来执行此操作。

SELECT Reverse(Parsename(Reverse(Replace(column1, ' > ', '.')), 1)) col1,
       Reverse(Parsename(Reverse(Replace(column1, ' > ', '.')), 2)) col2,
       Reverse(Parsename(Reverse(Replace(column1, ' > ', '.')), 3)) col3
FROM   tablename

演示

create table #test(   column1 varchar(500))
insert #test values
('ABC > DEF > GHI'),
('ABC > DEF > GHI'),
('ABC > DEF      '),
('ABC > DEF      '),
('ABC > DEF > GHI')

SELECT Reverse(Parsename(Reverse(Replace(column1, ' > ', '.')), 1)) col1,
       Reverse(Parsename(Reverse(Replace(column1, ' > ', '.')), 2)) col2,
       Reverse(Parsename(Reverse(Replace(column1, ' > ', '.')), 3)) col3
FROM   #test 

<强>结果:

col1    col2    col3
----    ----    ----
ABC     DEF     GHI
ABC     DEF     GHI
ABC     DEF     NULL
ABC     DEF     NULL
ABC     DEF     GHI

答案 1 :(得分:1)

您不应将分隔字符串存储在单个字段中,因为它取决于您。假设您别无选择,只能解析分隔的字符串,这是我经常使用的解析函数:

/********************************************************************************************
        Create Parse Function
********************************************************************************************/
CREATE FUNCTION dbo.FN_PARSE(@chunk VARCHAR(4000), @delimiter CHAR(1), @index INT )
RETURNS VARCHAR(1000)
AS
BEGIN
    DECLARE
        @curIndex INT = 0,
        @pos INT = 1,
        @prevPos INT = 0,
        @result VARCHAR(1000)
    WHILE @pos > 0
    BEGIN
        SET @pos =  CHARINDEX(@delimiter, @chunk, @prevPos);
        IF(@pos > 0)
        BEGIN -- Characters between position and previous position
            SET @result = SUBSTRING(@chunk, @prevPos, @pos-@prevPos)
        END
        ELSE
        BEGIN -- Last Delim
            SET @result = SUBSTRING(@chunk, @prevPos, LEN(@chunk))
        END
        IF(@index = @curIndex)
        BEGIN
            RETURN @result
        END
        SET @prevPos = @pos + 1
        SET @curIndex = @curIndex + 1;
    END
    RETURN '' -- Else Empty
END

用法很简单,使用三个参数调用函数,字段,分隔符和要返回的部分的索引。

SELECT dbo.FN_PARSE(column1,'>', 0) AS Col1
      ,dbo.FN_PARSE(column1,'>', 1) AS Col2
      ,dbo.FN_PARSE(column1,'>', 2) AS Col3
FROM YourTable

请注意,索引值从0开始。与PARSENAME()不同,这将处理超过4个部分,但这也可能效率较低。