SQL split或substring列值

时间:2018-03-13 09:14:35

标签: sql sql-server sql-server-2008 tsql

我有一个sql列和值/结构,如下所示:

ColumnA
ROOT/South America/Lima/Test/Test2

运行选择查询我想提取“Lima”作为列值。我无法使用分割字符串,或子字符串。

有什么想法吗?

4 个答案:

答案 0 :(得分:2)

这是我获取任何分隔字符串的第n部分的方法:

DECLARE @mockupTable TABLE(ID INT IDENTITY, YourColumn VARCHAR(1000));

INSERT INTO @mockupTable VALUES('ROOT/South America/Lima/Test/Test2')
                              ,('Too/short')
                              ,('Three/parts/valid');

- 拆分是单行

SELECT *
      ,CAST('<x>' + REPLACE(YourColumn,'/','</x><x>') + '</x>' AS XML).value('/x[3]','nvarchar(max)') AS ThirdPart
FROM @mockupTable;

如果您的分隔字符串可能包含禁止使用XML的字符(即&, < and >,那么您必须逃避它们(但这很容易):

请改用

      ,CAST('<x>' + REPLACE((SELECT YourColumn [*] FOR XML PATH('')),'/','</x><x>') + '</x>' AS XML).value('/x[3]','nvarchar(max)') AS ThirdPart

一些解释

使用/替换分隔符</x><x>可以获得类似XML的字符串,可以将其转换为

<x>ROOT</x>
<x>South America</x>
<x>Lima</x>
<x>Test</x>
<x>Test2</x>

XML方法.value()允许使用XQuery获取第三个<x>。一个优点:如果没有第三个元素,这不会中断,只需返回NULL

答案 1 :(得分:1)

那里有点但它有效。基于递归cte。您可以设置分隔符,开始和结束。

declare @T table (iden int identity, col1 varchar(100));
insert into @T(col1) values
       ('ROOT/South America/Lima/Test/Test2')
     , ('ROOT/South America/Peru/Test/Test2')
     , ('ROOT/South America/Venuzuala')
     , ('ROOT/South America/'); 
declare @split char(1) = '/';
declare @start int = 2;
declare @end int = 3
select @split, @start, @end;
with cte as 
(  select t.iden, t.col1, charindex(@split, t.col1) as pos    , 1 as cnt
   from @T t
   union all 
   select t.iden, t.col1, charindex(@split, t.col1, t.pos + 1), cnt + 1 
   from cte t 
   where charindex(@split, t.col1, t.pos + 1) > 0 
     and cnt+1 <= @end
)
--select * from cte order by iden, cnt;
select --t1.*, t2.*, 
       SUBSTRING(t1.col1, t1.pos+1, t2.pos-t1.pos-1) as bingo
from cte t1 
join cte t2 
  on t2.iden = t1.iden 
 and t1.cnt = @start 
 and t2.cnt = @end
order by t1.iden;

答案 2 :(得分:0)

在SQL Server中,您可以使用以下内容:

select  
substring(s.d,
       CHARINDEX ( '/' , s.d ,CHARINDEX ( '/' , s.d ,1 ) +1 ) +1,
       (   (CHARINDEX ( '/' , s.d ,CHARINDEX ( '/' , s.d ,(CHARINDEX ( '/' , s.d ,1 ) +1 ) ) +1 ))-
           (CHARINDEX ( '/' , s.d ,CHARINDEX ( '/' , s.d ,1 ) +1 ) +1) 
        )
       ) '3rd'
from s

这将在第二个“/”和第三个“/”之间给出文本,而不管文本的长度如何。

答案 3 :(得分:0)

declare @t varchar(max) = 'ROOT/South America/Lima/Test/Test2'
select * from (
select 
[value]
,ROW_NUMBER() Over (Order by (select null )) [Level]
from string_split( @t , '/')
) d
where d.Level = 3

上面的代码使用更简单的逻辑进行相同处理,将文本用'/'结果分割为“ String_Split”行,然后使用row_number()获得结果的顺序,如果没有排序,则每个数字都是一个级别按照陈述“(选择空)”的顺序完成 结果是,将级别编号添加到where statement将获得我们想要的级别值的上方,上方将显示级别3