SQL拆分或子字符串列值
我有一个sql列和值/结构,如下所示:SQL拆分或子字符串列值,sql,sql-server,sql-server-2008,tsql,Sql,Sql Server,Sql Server 2008,Tsql,我有一个sql列和值/结构,如下所示: ColumnA ROOT/South America/Lima/Test/Test2 运行select查询时,我想将Lima提取为列值。我无法使拆分字符串或子字符串正常工作 有什么想法吗?这是我获取任何分隔字符串的第n部分的方法: DECLARE @mockupTable TABLE(ID INT IDENTITY, YourColumn VARCHAR(1000)); INSERT INTO @mockupTable VALUES('ROOT/Sou
ColumnA
ROOT/South America/Lima/Test/Test2
运行select查询时,我想将Lima提取为列值。我无法使拆分字符串或子字符串正常工作
有什么想法吗?这是我获取任何分隔字符串的第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');
-劈裂是一种单衬套:
XML的method.value允许使用XQuery获取第三个。一个优点是:如果没有第三个元素,它就不会中断,只需返回NULL。稍微有一点,但它可以工作。基于递归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;
上面的代码同样具有更简单的逻辑,通过“/”结果将文本拆分为行String\u split,然后使用行编号来获得结果的顺序,如果没有按照station选择null的顺序进行排序,则每个编号都是一个级别
因此,通过在where station中添加级别编号,将获得我们想要的级别值,上面将显示级别3sql server 2008。在路径深度可能不固定的情况下,是否将Lima视为左侧的第三个条目,或右侧的第三个条目?确切地说,总是从左边开始的第三个条目。什么版本?2016支持字符串\拆分字符串、分隔符
,CAST('<x>' + REPLACE((SELECT YourColumn [*] FOR XML PATH('')),'/','</x><x>') + '</x>' AS XML).value('/x[3]','nvarchar(max)') AS ThirdPart
<x>ROOT</x>
<x>South America</x>
<x>Lima</x>
<x>Test</x>
<x>Test2</x>
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;
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