我的字符串实际上只有一个规则:总是有一个'/'分隔符,其频率为2。
示例:
1/2/3
111/222222/3
asdf/dd/eds
如何在没有string_split()的情况下执行此操作或创建新表以将该字符串分成3个?
我做了几次尝试,但是总有些不正确。
在下面的示例中,假设“ str”是上述示例之一。
select
substring(str,0,charindex('/',str,0)) as first,
substring(str,charindex('/',str,0) + 1,charindex('/',strcharindex('/',strcharindex('/',str,0) + 1))) as 2nd,
--3rd
答案 0 :(得分:2)
我发现使用apply
最简单:
select v1.first, v2.second, v2.third
from (values ('a/b/c')) t(str) cross apply
(values (left(t.str, charindex('/', t.str) - 1),
stuff(t.str, 1, charindex('/', t.str), '')
)
) v1(first, rest) cross apply
(values (left(v1.rest, charindex('/', v1.rest) - 1),
stuff(v1.rest, 1, charindex('/', v1.rest), '')
)
) v2(second, third);
Here是db <>小提琴。
您可以将stuff()
和left()
视为substring()
的简写。
还有其他选择,例如split()
函数。不幸的是,内置的split函数没有为生成的字符串提供索引。因此,您可以获得零件,但无法按顺序购买。
您还可以使用递归CTE和XML设计解决方案。对于这种特定的问题,我只是喜欢使用这种方法。
答案 1 :(得分:2)
根据您的要求,但不需要LEN()
declare @var varchar(64) = '111/222222/3'
select
substring(@var,1,charindex('/',@var) - 1)
,substring(@var,charindex('/',@var) + 1,charindex('/',substring(@var,charindex('/',@var) + 1,99)) - 1)
,substring(substring(@var,charindex('/',@var) + 1,99),charindex('/',substring(@var,charindex('/',@var) + 1,99)) + 1,99)
在任何地方看到99都会将其更改为字符串的最大长度,或者将8000更改为字符串全部
答案 2 :(得分:2)
在这种情况下,最简单的解决方案是(ab)使用parsename
-使用cross apply
和replace
:
SELECT PARSENAME(val, 3) As col1,
PARSENAME(val, 2) As col2,
PARSENAME(val, 1) As col3
FROM Table
CROSS APPLY
(
SELECT REPLACE(str, '/', '.') As val
) x
在马丁·史密斯(Martin Smith)评论之后-
只有在定界符之间的字符串不超过128个字符且不包含点的情况下,这才起作用(尽管这可以用更多的replace语句解决,但这会使整个事情变得更麻烦)答案 3 :(得分:2)
另一个选择是一点XML
示例
Declare @YourTable table (SomeCol varchar(50))
Insert Into @YourTable values
('1/2/3')
,('111/222222/3')
,('asdf/dd/eds')
Select A.*
,B.*
From @YourTable A
Cross Apply (
Select Pos1 = xDim.value('/x[1]','varchar(max)')
,Pos2 = xDim.value('/x[2]','varchar(max)')
,Pos3 = xDim.value('/x[3]','varchar(max)')
From (Select Cast('<x>' + replace((Select replace(SomeCol,'/','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml) as xDim) as B1
) B
返回
SomeCol Pos1 Pos2 Pos3
1/2/3 1 2 3
111/222222/3 111 222222 3
asdf/dd/eds asdf dd eds