我有一个sql列和值/结构,如下所示:
ColumnA
ROOT/South America/Lima/Test/Test2
运行选择查询我想提取“Lima”作为列值。我无法使用分割字符串,或子字符串。
有什么想法吗?
答案 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