检索带数字的第一个子字符串?
Retrieve the first substring with numbers?
我正在尝试检索带有数字的列的第一个子字符串(以 space 作为分隔符)。
例子是
从"Volvo L90H Pye No2"
得到"L90H"
从"Vio55-6B Pipeline Civil"
得到"Vio55-6B"
您可能想试试这个。使用 string_split
函数和 patindex
with cte as (
select 'Volvo L90H Pye No2' as val
union
select 'Vio55-6B Pipeline Civil')
select max(t.rn), t.value, t.val
from
(select row_number() over(partition by val order by (select null)) rn, t2.value, t1.val
from cte t1
cross apply string_split(t1.val, ' ') t2
where patindex('%[0-9]%', t2.value) > 0) t
where t.rn = 1
group by t.val, t.value
输出:
您可以 string_split
您的值,然后 select 带有数字的行。像这样。
declare @tbl table(id int,detail nvarchar(100))
insert @tbl(id,detail) values
(1,'Volvo L90H Pye No2'),(2,'Vio55-6B Pipeline Civil')
;with cte as (
select id,value,ROW_NUMBER() over(partition by id order by id) rn
from @tbl
cross apply string_split(detail,' ')
where value like '%[0-9]%'
)
select * from cte
where rn=1
接受的答案使用 STRING_SPLIT()
。这表明您至少使用 v2016。重要的是要知道,STRING_SPLIT()
是垃圾(在大多数情况下),因为它可能不会 return 预期顺序的片段。最糟糕的是:这几乎永远有效。它会通过你所有的内部测试,但总有一天它会在生产部署后产生愚蠢的错误。
STRING_SPLIT()
是在 v2016 中引入的,JSON 支持也是如此。检查以下解决方案以找到位置安全的分离器:
DECLARE @tbl TABLE(ID INT IDENTITY,YourString VARCHAR(100))
INSERT INTO @tbl VALUES
('Volvo L90H Pye No2'),('Vio55-6B Pipeline Civil');
WITH Numbered AS
(
SELECT t.ID
,t.YourString
,A.*
,ROW_NUMBER() OVER(PARTITION BY t.ID ORDER BY A.[key]) AS RowNumber
FROM @tbl t
CROSS APPLY OPENJSON(CONCAT('["',REPLACE(t.YourString,' ','","'),'"]')) A
WHERE A.[value] LIKE '%[0-9]%'
)
SELECT ID
,YourString
,[value] AS FirstFragmentWithNumber
FROM Numbered
WHERE RowNumber=1;
简而言之:我们使用简单的字符串方法将您的字符串转换为 JSON 数组。
a b c => ["a","b","c"]
OPENSJON
将读取此数组和 return 其 value
列中的所有项目,而 key
列将包含每个项目的位置。
使用 ROW_NUMBER()
和 PARTITION BY
将为每个 ID
标记每个 第一 行 1
。这个我们可以用在最后的 WHERE
.
我正在尝试检索带有数字的列的第一个子字符串(以 space 作为分隔符)。
例子是
从"Volvo L90H Pye No2"
得到"L90H"
从"Vio55-6B Pipeline Civil"
得到"Vio55-6B"
您可能想试试这个。使用 string_split
函数和 patindex
with cte as (
select 'Volvo L90H Pye No2' as val
union
select 'Vio55-6B Pipeline Civil')
select max(t.rn), t.value, t.val
from
(select row_number() over(partition by val order by (select null)) rn, t2.value, t1.val
from cte t1
cross apply string_split(t1.val, ' ') t2
where patindex('%[0-9]%', t2.value) > 0) t
where t.rn = 1
group by t.val, t.value
输出:
您可以 string_split
您的值,然后 select 带有数字的行。像这样。
declare @tbl table(id int,detail nvarchar(100))
insert @tbl(id,detail) values
(1,'Volvo L90H Pye No2'),(2,'Vio55-6B Pipeline Civil')
;with cte as (
select id,value,ROW_NUMBER() over(partition by id order by id) rn
from @tbl
cross apply string_split(detail,' ')
where value like '%[0-9]%'
)
select * from cte
where rn=1
接受的答案使用 STRING_SPLIT()
。这表明您至少使用 v2016。重要的是要知道,STRING_SPLIT()
是垃圾(在大多数情况下),因为它可能不会 return 预期顺序的片段。最糟糕的是:这几乎永远有效。它会通过你所有的内部测试,但总有一天它会在生产部署后产生愚蠢的错误。
STRING_SPLIT()
是在 v2016 中引入的,JSON 支持也是如此。检查以下解决方案以找到位置安全的分离器:
DECLARE @tbl TABLE(ID INT IDENTITY,YourString VARCHAR(100))
INSERT INTO @tbl VALUES
('Volvo L90H Pye No2'),('Vio55-6B Pipeline Civil');
WITH Numbered AS
(
SELECT t.ID
,t.YourString
,A.*
,ROW_NUMBER() OVER(PARTITION BY t.ID ORDER BY A.[key]) AS RowNumber
FROM @tbl t
CROSS APPLY OPENJSON(CONCAT('["',REPLACE(t.YourString,' ','","'),'"]')) A
WHERE A.[value] LIKE '%[0-9]%'
)
SELECT ID
,YourString
,[value] AS FirstFragmentWithNumber
FROM Numbered
WHERE RowNumber=1;
简而言之:我们使用简单的字符串方法将您的字符串转换为 JSON 数组。
a b c => ["a","b","c"]
OPENSJON
将读取此数组和 return 其 value
列中的所有项目,而 key
列将包含每个项目的位置。
使用 ROW_NUMBER()
和 PARTITION BY
将为每个 ID
标记每个 第一 行 1
。这个我们可以用在最后的 WHERE
.