提取字符串中第 2 次出现字符的权利
Extract right of 2nd occurrence of character in string
我正在使用 SQL Server 2014。
我有一个 table,它有一个名为 '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
我需要做两件事:
- 提取第二个“ ”和第三个“ ”之间的数字
结果:
101
101
123
12a
- 提取从第三个“ ”到第一个“;”的文本结果:
My Street
My Street
My Crescent
My Avenue
我该怎么做?
我试过:
SELECT CAST('<x>' + REPLACE(addr, ' ', '</x><x>') + '</x>' AS XML).value('/x[1]', 'varchar(200)') from mytable;
但这会导致 'ROOM'。
更新:
为了提取第 2 和第 3 之间的数字,我使用了以下内容:
SELECT CAST('<x>' + REPLACE(addr, ' ', '</x><x>') + '</x>' AS XML).value('/x[3]', 'varchar(200)') from MyTable;
如何从第三个“ ”和第一个“;”中提取虽然?
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 个 ' ' 之间获取您的号码。
Thanks @JoeJ - how do I modify it to say from 3rd ' ' to first ';' ? – Michael
@迈克尔,
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
它returns:
我正在使用 SQL Server 2014。
我有一个 table,它有一个名为 '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
我需要做两件事:
- 提取第二个“ ”和第三个“ ”之间的数字 结果:
101
101
123
12a
- 提取从第三个“ ”到第一个“;”的文本结果:
My Street
My Street
My Crescent
My Avenue
我该怎么做?
我试过:
SELECT CAST('<x>' + REPLACE(addr, ' ', '</x><x>') + '</x>' AS XML).value('/x[1]', 'varchar(200)') from mytable;
但这会导致 'ROOM'。
更新:
为了提取第 2 和第 3 之间的数字,我使用了以下内容:
SELECT CAST('<x>' + REPLACE(addr, ' ', '</x><x>') + '</x>' AS XML).value('/x[3]', 'varchar(200)') from MyTable;
如何从第三个“ ”和第一个“;”中提取虽然?
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 个 ' ' 之间获取您的号码。
Thanks @JoeJ - how do I modify it to say from 3rd ' ' to first ';' ? – Michael
@迈克尔,
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
它returns: