检索带数字的第一个子字符串?

Retrieve the first substring with numbers?

我正在尝试检索带有数字的列的第一个子字符串(以 space 作为分隔符)。

例子是

  1. 从"Volvo L90H Pye No2"

  2. 得到"L90H"
  3. 从"Vio55-6B Pipeline Civil"

  4. 得到"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.