Sql server 提取字符串中字符第二次出现的权限
我正在使用SQL Server 2014 我有一个表,其中有一个名为“addr”的字段,其中包含如下字符串值:Sql server 提取字符串中字符第二次出现的权限,sql-server,string,tsql,substring,charindex,Sql Server,String,Tsql,Substring,Charindex,我正在使用SQL Server 2014 我有一个表,其中有一个名为“addr”的字段,其中包含如下字符串值: ROOM 1 101 My Street; My Town ROOM 2 101 My Street; My Town ROOM A 123 My Crescent; My Old Town ROOM A 12a My Avenue; My Very Old Town SELECT CAST('<x>' + REPLACE(addr, ' ', '</x>&l
ROOM 1 101 My Street; My Town
ROOM 2 101 My Street; My Town
ROOM A 123 My Crescent; My Old Town
ROOM A 12a My Avenue; My Very Old Town
SELECT CAST('<x>' + REPLACE(addr, ' ', '</x><x>') + '</x>' AS XML).value('/x[3]', 'varchar(200)') from MyTable;
我需要做两件事:
SELECT CAST('<x>' + REPLACE(addr, ' ', '</x><x>') + '</x>' AS XML).value('/x[1]', 'varchar(200)') from mytable;
从mytable中选择CAST(''+REPLACE(addr','')+''作为XML);
但这会导致“房间”
更新:
为了提取第二个和第三个之间的数字,我使用了以下方法:
ROOM 1 101 My Street; My Town
ROOM 2 101 My Street; My Town
ROOM A 123 My Crescent; My Old Town
ROOM A 12a My Avenue; My Very Old Town
SELECT CAST('<x>' + REPLACE(addr, ' ', '</x><x>') + '</x>' AS XML).value('/x[3]', 'varchar(200)') from MyTable;
从MyTable中选择CAST(''+REPLACE(addr','')+''作为XML);
如何从第三个“”和第一个“;”中提取尽管如此?Joe J在评论中回答:
如果您想在一个select语句中实现所有功能,可以使用CHARINDEX和SUBSTRING的可怕组合。像这样的
select SUBSTRING(addr, charindex(' ', addr, charindex(' ', addr, 1) + 1) + 1,charindex(' ', addr, charindex(' ', addr, charindex(' ', addr, 1) + 1) + 1) - charindex(' ', addr, charindex(' ', addr, 1) + 1) -1)
将在第2和第3个“”之间获取您的号码
谢谢@JoeJ-我如何将其修改为从第三个“;”到第一个“?”迈克尔
@迈克尔
select SUBSTRING(addr,charindex(' ', addr, charindex(' ', addr, charindex(' ', addr, 1) + 1) + 1) + 1,charindex(';', addr, 1) - charindex(' ', addr, charindex(' ', addr, charindex(' ', addr, 1) + 1) + 1) -1) will do between the third ' ' and the first ';'.
正如我所说,这非常可怕,而且严格依赖于每个记录中的空格等完全相同的位置。Joe J在评论中回答:
如果您想在一个select语句中实现所有功能,可以使用CHARINDEX和SUBSTRING的可怕组合。像这样的
select SUBSTRING(addr, charindex(' ', addr, charindex(' ', addr, 1) + 1) + 1,charindex(' ', addr, charindex(' ', addr, charindex(' ', addr, 1) + 1) + 1) - charindex(' ', addr, charindex(' ', addr, 1) + 1) -1)
将在第2和第3个“”之间获取您的号码
谢谢@JoeJ-我如何将其修改为从第三个“;”到第一个“?”迈克尔
@迈克尔
select SUBSTRING(addr,charindex(' ', addr, charindex(' ', addr, charindex(' ', addr, 1) + 1) + 1) + 1,charindex(';', addr, 1) - charindex(' ', addr, charindex(' ', addr, charindex(' ', addr, 1) + 1) + 1) -1) will do between the third ' ' and the first ';'.
正如我所说,这是非常可怕的,而且严格依赖于空格等。在每个记录中都完全位于同一个位置。如果您的要求不会随时间发生太大变化,您可以这样严格地编程:
with t as (
select 'ROOM 1 101 My Street; My Town' a union all
select 'ROOM 2 101 My Street; My Town' a union all
select 'ROOM A 123 My Crescent; My Old Town' a union all
select 'ROOM A 12a My Avenue; My Very Old Town' a )
, t2 as (
select a, PATINDEX('% %', a) pi1,
PATINDEX('% %', SUBSTRING(a, 1 + nullif(PATINDEX('% %', a), 0), LEN(a))) pi2,
PATINDEX('% %', SUBSTRING(a, 1 + PATINDEX('% %', SUBSTRING(a, 1 + nullif(PATINDEX('% %', a), 0), LEN(a))) + nullif(PATINDEX('% %', a), 0), LEN(a))) pi3,
PATINDEX('%;%', SUBSTRING(a, 1 + PATINDEX('% %', SUBSTRING(a, 1 + PATINDEX('% %', SUBSTRING(a, 1 + nullif(PATINDEX('% %', a), 0), LEN(a))) + nullif(PATINDEX('% %', a), 0), LEN(a))) + PATINDEX('% %', SUBSTRING(a, 1 + nullif(PATINDEX('% %', a), 0), LEN(a))) + nullif(PATINDEX('% %', a), 0), LEN(a))) pi4
from t
)
select a, SUBSTRING(a, pi1, pi2) s1, SUBSTRING(a, pi1 + pi2, pi3) s2, SUBSTRING(a, pi1 + pi2 + pi3, pi4) s3, SUBSTRING(a, pi1 + pi2 + pi3 + pi4, len(a)) s4
from t2
它返回:
如果您的需求不会随着时间的推移发生太多变化,您可以像这样严格地编程:
with t as (
select 'ROOM 1 101 My Street; My Town' a union all
select 'ROOM 2 101 My Street; My Town' a union all
select 'ROOM A 123 My Crescent; My Old Town' a union all
select 'ROOM A 12a My Avenue; My Very Old Town' a )
, t2 as (
select a, PATINDEX('% %', a) pi1,
PATINDEX('% %', SUBSTRING(a, 1 + nullif(PATINDEX('% %', a), 0), LEN(a))) pi2,
PATINDEX('% %', SUBSTRING(a, 1 + PATINDEX('% %', SUBSTRING(a, 1 + nullif(PATINDEX('% %', a), 0), LEN(a))) + nullif(PATINDEX('% %', a), 0), LEN(a))) pi3,
PATINDEX('%;%', SUBSTRING(a, 1 + PATINDEX('% %', SUBSTRING(a, 1 + PATINDEX('% %', SUBSTRING(a, 1 + nullif(PATINDEX('% %', a), 0), LEN(a))) + nullif(PATINDEX('% %', a), 0), LEN(a))) + PATINDEX('% %', SUBSTRING(a, 1 + nullif(PATINDEX('% %', a), 0), LEN(a))) + nullif(PATINDEX('% %', a), 0), LEN(a))) pi4
from t
)
select a, SUBSTRING(a, pi1, pi2) s1, SUBSTRING(a, pi1 + pi2, pi3) s2, SUBSTRING(a, pi1 + pi2 + pi3, pi4) s3, SUBSTRING(a, pi1 + pi2 + pi3 + pi4, len(a)) s4
from t2
它返回:
使用支持顺序位置的字符串拆分器(我建议使用
DelimitedSplit8K_LEAD
),这是一个非常有用的方法。@Larnu我不确定我是否完全理解-这是SQL函数吗?是的,@Michael。如果您想在一个select语句中实现所有功能,可以使用CHARINDEX
和SUBSTRING
的可怕组合。类似这样的select子字符串(addr,charindex(“”,addr,charindex(“”,addr,1)+1,charindex(“”,addr,charindex(“”,addr,charindex(“”,addr,1)+1)-charindex(“”,addr,charindex(“”,addr,1)+1)
将获得第二个和第三个之间的数字。@Michael,select子字符串(addr,charindex)(“”,addr,charindex(“”,addr,charindex(“”,addr,1)+1)+1,charindex(“”,addr,1)-charindex(“”,addr,charindex(“”,addr,charindex(“”,addr,1)+1)-1)
将在第三个“”和第一个“;”之间执行。正如我所说,这非常可怕,并且严格依赖于空格等。每个记录中的位置都完全相同。使用支持顺序位置的字符串拆分器(我建议使用DelimitedSplit8K_LEAD
)这是一个可怕的组合。@Larnu我不确定我是否完全理解-这是一个SQL函数吗?是的,@Michael。如果你想在一个select语句中实现这一切,你可以使用CHARINDEX
和SUBSTRING
。类似的选择子字符串(addr,CHARINDEX('',addr,CHARINDEX('',addr,1)+1,CHARINDEX)(“”,addr,charindex(“”,addr,charindex(“”,addr,1)+1)-charindex(“”,addr,charindex(“”,addr,1)+1)-1
将获取第二个和第三个之间的数字。@Michael,选择子字符串(addr,charindex(“”,addr,charindex(“”,addr,charindex(“”,addr,1)+1),charindex(“”,addr,1)+1)-charindex(“”,addr,charindex(“”,addr,charindex(“”,addr,1)+1)+1)-1)
将在第三个“”和第一个“;”。正如我所说,这非常可怕,并且严格依赖于空格等。在每个记录中都完全位于同一位置。