SQL查询使用patindex从字符串中提取数字

时间:2018-10-16 15:36:27

标签: sql-server

下面提到的查询运行良好,并从字符串中提取数字:

DECLARE @string varchar(100)

SET @string = N'"Total Comp A Commitments" means the aggregate of the Comp A Commitments, being £2,500,000 at the date of this Agreement.'

-- loop till there are characters left in a string
print LEN(@string)

WHILE PATINDEX('%[^0-9]%',@string) <> 0
BEGIN
    -- replace characters with empty space
    print 'iN lOOP'
    SET @string = STUFF(@string,PATINDEX('%[^0-9]%',@string),1,'')
END
SELECT @string

但是当字符串具有多个数字值时,我无法使其工作:

  

String = N'“总补偿A承诺”是指补偿的总和   承诺额,在本协议签署之日为2,500,000英镑。 “总   合同B承诺”是指合同B承诺的总和,   在本协议签订之日为2,500,000英镑。 “总补偿C   承诺”是指Comp C承诺的总和,即   协议签订之日起为2,500,000英镑。”

1 个答案:

答案 0 :(得分:0)

如果对表值函数开放,请考虑以下内容。

我厌倦了提取字符串(左,右,charindex,patindex等),我修改了一个解析函数以接受两个非相似的定界符。在这种情况下,'£'' '

作为TVF,如果您的数据在表中,则很容易将其合并到CROSS APPLY中。

示例

Declare @S varchar(max) = 'Total Comp A Commitments" means the aggregate of the Comp A Commitments, being £2,500,000 at the date of this Agreement. "Total Comp B Commitments" means the aggregate of the Comp B Commitments, being £2,500,000 at the date of this Agreement. "Total Comp C Commitments" means the aggregate of the Comp C Commitments, being £2,500,000 at the date of this Agreement.'

Select *
      ,AsMoney = try_convert(money,RetVal) 
 From  [dbo].[tvf-Str-Extract](@S,'£',' ')
 Where try_convert(money,RetVal) is not null

返回

RetSeq  RetPos  RetVal      AsMoney
2       81      2,500,000   2500000.00
3       203     2,500,000   2500000.00
4       325     2,500,000   2500000.00

感兴趣的TVF

CREATE FUNCTION [dbo].[tvf-Str-Extract] (@String varchar(max),@Delimiter1 varchar(100),@Delimiter2 varchar(100))
Returns Table 
As
Return (  

with   cte1(N)   As (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N)),
       cte2(N)   As (Select Top (IsNull(DataLength(@String),0)) Row_Number() over (Order By (Select NULL)) From (Select N=1 From cte1 N1,cte1 N2,cte1 N3,cte1 N4,cte1 N5,cte1 N6) A ),
       cte3(N)   As (Select 1 Union All Select t.N+DataLength(@Delimiter1) From cte2 t Where Substring(@String,t.N,DataLength(@Delimiter1)) = @Delimiter1),
       cte4(N,L) As (Select S.N,IsNull(NullIf(CharIndex(@Delimiter1,@String,s.N),0)-S.N,8000) From cte3 S)

Select RetSeq = Row_Number() over (Order By N)
      ,RetPos = N
      ,RetVal = left(RetVal,charindex(@Delimiter2,RetVal)-1) 
 From  (
        Select *,RetVal = Substring(@String, N, L) 
         From  cte4
       ) A
 Where charindex(@Delimiter2,RetVal)>1

)
/*
Max Length of String 1MM characters

Declare @String varchar(max) = 'Dear [[FirstName]] [[LastName]], ...'
Select * From [dbo].[tvf-Str-Extract] (@String,'[[',']]')
*/
  

编辑-请求的金额

Select AsMoney = sum(try_convert(money,RetVal) )
 From  [dbo].[tvf-Str-Extract](@S,'£',' ')

返回

7500000.00