T-SQL 从字符串中提取数字以及介于两者之间的所有内容
T-SQL Extract Numbers from a string and everything in between
我正在使用 SQL Server 2014。
我了解如何使用 PATINDEX (Query to get only numbers from a string) 从字符串中提取数字,但是,如果它们实际上是我还需要提取的数字之间的字符串值,我将如何添加。例如;
这是我的字符串:
15-19 Smith Street
1-3 Smith Street
我需要:
15-19
1-3
此外,如果有后缀,我需要将其提取为单独的字段:
147a York Road
我需要 147 作为 1 个字段,字母 'a' 作为另一个字段
如何在 T-SQL 中实现此目标?
您可以将 charindex()
与 patindex()
一起使用:
select substring(col, patindex('%[0-9]%', col),
len(col) - charindex(' ', col, patindex('%[0-9]%', col)) - 1
) as col
它可能看起来有点令人费解,但您可以使用通用 Table 表达式 (CTE) 和递归来完成它。 CTE 循环遍历字符串中的字符,并根据它们的内容不断将它们添加到任一列的输出列中。
declare @a table (v varchar(20))
insert into @a
values
('1-15 Something'), ('147a Something else'),
('15 dkdkjg'), ('154'),
('15-3'), ('16-9 Some lane')
update @a set v = trim(v);
with
cte as
(select v, max(len(v)) over () maxLen, 1 curr, 0 final,
cast('' as varchar(100)) st, cast('' as varchar(100)) st2
from @a
union all
select v, maxLen, curr+1 curr,
iif(len(v) = curr or substring(v, curr+1, 1) = ' ', 1, 0) final,
cast(iif(substring(v, curr, 1) like '[0-9]'
or substring(v, curr+1, 1) like '[0-9]',
concat(st, substring(v, curr, 1)), st) as varchar(100)) st,
cast(iif(substring(v, curr, 1) not like '[0-9]'
and substring(v, curr+1, 1) not like '[0-9]',
concat(st2, substring(v, curr, 1)), st2) as varchar(100)) st2
from cte
where final = 0)
select v, st, st2
from cte
where final = 1
您可以使用下面的编码变成USER-DEFINED FUNCTION
。
它可以满足你所有的3种情况[15-19 Smith Street,1-3 Smith Street,147a York Road]
DECLARE @strAlphaNumeric VARCHAR(MAX)='15-19 Smith Street'
DECLARE @intAlpha INT
SET @intAlpha = PATINDEX('%[a-z]%', @strAlphaNumeric)
BEGIN
WHILE @intAlpha >0
BEGIN
SET @strAlphaNumeric = STUFF(@strAlphaNumeric, @intAlpha, 1, '' )
SET @intAlpha = PATINDEX('%[a-z]%', @strAlphaNumeric )
END
END
select ISNULL(@strAlphaNumeric,0)
我正在使用 SQL Server 2014。
我了解如何使用 PATINDEX (Query to get only numbers from a string) 从字符串中提取数字,但是,如果它们实际上是我还需要提取的数字之间的字符串值,我将如何添加。例如;
这是我的字符串:
15-19 Smith Street
1-3 Smith Street
我需要:
15-19
1-3
此外,如果有后缀,我需要将其提取为单独的字段:
147a York Road
我需要 147 作为 1 个字段,字母 'a' 作为另一个字段
如何在 T-SQL 中实现此目标?
您可以将 charindex()
与 patindex()
一起使用:
select substring(col, patindex('%[0-9]%', col),
len(col) - charindex(' ', col, patindex('%[0-9]%', col)) - 1
) as col
它可能看起来有点令人费解,但您可以使用通用 Table 表达式 (CTE) 和递归来完成它。 CTE 循环遍历字符串中的字符,并根据它们的内容不断将它们添加到任一列的输出列中。
declare @a table (v varchar(20))
insert into @a
values
('1-15 Something'), ('147a Something else'),
('15 dkdkjg'), ('154'),
('15-3'), ('16-9 Some lane')
update @a set v = trim(v);
with
cte as
(select v, max(len(v)) over () maxLen, 1 curr, 0 final,
cast('' as varchar(100)) st, cast('' as varchar(100)) st2
from @a
union all
select v, maxLen, curr+1 curr,
iif(len(v) = curr or substring(v, curr+1, 1) = ' ', 1, 0) final,
cast(iif(substring(v, curr, 1) like '[0-9]'
or substring(v, curr+1, 1) like '[0-9]',
concat(st, substring(v, curr, 1)), st) as varchar(100)) st,
cast(iif(substring(v, curr, 1) not like '[0-9]'
and substring(v, curr+1, 1) not like '[0-9]',
concat(st2, substring(v, curr, 1)), st2) as varchar(100)) st2
from cte
where final = 0)
select v, st, st2
from cte
where final = 1
您可以使用下面的编码变成USER-DEFINED FUNCTION
。
它可以满足你所有的3种情况[15-19 Smith Street,1-3 Smith Street,147a York Road]
DECLARE @strAlphaNumeric VARCHAR(MAX)='15-19 Smith Street'
DECLARE @intAlpha INT
SET @intAlpha = PATINDEX('%[a-z]%', @strAlphaNumeric)
BEGIN
WHILE @intAlpha >0
BEGIN
SET @strAlphaNumeric = STUFF(@strAlphaNumeric, @intAlpha, 1, '' )
SET @intAlpha = PATINDEX('%[a-z]%', @strAlphaNumeric )
END
END
select ISNULL(@strAlphaNumeric,0)