如何从SQLServer表中的文本字段中获取精确数字

如何从SQLServer表中的文本字段中获取精确数字,sql,sql-server,Sql,Sql Server,我有一张表,包括客户、联系人、姓名、收入。我想从收入列中获取客户净收入作为一个值。 最终输出如下所示。我的表中有100000多行。 AF-4838-加扬先生是一名医生,他的工资为95000卢比。他有一块椰子地,月收入为150000卢比。他的费用为55000卢比,净收入为190000卢比 AV-7392-月净收入为55000/- AF-3746——妻子的工资——25000卢比,他是一名店主,每月从商店获得的收入=100000卢比/——扣除45000卢比的费用后,当月的净收入为80000卢比/

我有一张表,包括客户、联系人、姓名、收入。我想从收入列中获取客户净收入作为一个值。

最终输出如下所示。我的表中有100000多行。

AF-4838-加扬先生是一名医生,他的工资为95000卢比。他有一块椰子地,月收入为150000卢比。他的费用为55000卢比,净收入为190000卢比

AV-7392-月净收入为55000/-

AF-3746——妻子的工资——25000卢比,他是一名店主,每月从商店获得的收入=100000卢比/——扣除45000卢比的费用后,当月的净收入为80000卢比/


AF-6453-每月总净收入为60000/

您可以使用嵌套的CHARINDEX函数获取子字符串“净收入”起点后的第一个数值。

自定义项将基于两个不相似的分隔符提取字符串

您可能会注意到,我将“净收入”替换为“| |净收入”,这样我的第一个delimeter将是“| | |”,并在字符串末尾添加一个“/”,以便我的第二个delimeter为“/”。这是为了确保字符串至少有一个“/”

示例

Select A.customer_contact_no
      ,Income = try_convert(int,right(B.RetVal,charindex(' ',replace(reverse(RetVal),'.',' '))-1))
 From  YourTable A
 Cross Apply [dbo].[udf-Str-Extract](replace([Income],'Net Income','|||Net Income')+'/','|||','/') B
 Where RetVal Like 'Net Income%'
返回

有兴趣的UDF

CREATE FUNCTION [dbo].[udf-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].[udf-Str-Extract] (@String,'[[',']]')
*/
如果您愿意,也可以使用CTE

declare @test table
(
    val varchar(300)
)

INSERT INTO @test 
select 'blah blah blah net income blah blah 86000'

INSERT INTO @test 
select 'blah blah blah net income blah blah 4000, expenses 0'

INSERT INTO @test 
select 'blah blah blah net income blah blah 80,000 g'

INSERT INTO @test 
select 'blah expenses are 60 blah blah net income blah blah 6000 blah '

INSERT INTO @test 
select 'blah net income for whatever 6000. blah blah net income blah blah 86000'


;WITH FindNetIncomeString AS (select val, len(val) - charindex('emocni ten', reverse(val)) as  net from @test),
      FindFirstNumeric AS (select substring(val,net,len(val) - net + 1) as val, PATINDEX('%[0-9]%',substring(val,net,len(val) - net + 1)) as inc from FindNetIncomeString),
      GetNumericOnly AS (select substring(val, inc, len(val) - inc + 1) as val from FindFirstNumeric),
      GetNetIncome as (select replace(substring(val,0, CASE WHEN PATINDEX('%[^0-9,]%',val) = 0 THEN len(val) + 1 ELSE PATINDEX('%[^0-9,]%',val) END),',','') as NetIncomes from GetNumericOnly)
select NetIncomes
from GetNetIncome;
结果

NetIncomes
------
86000
4000
80000
6000
86000
非CTE测试:


使用CTE进行测试:

鉴于文本的性质,SQL Server不是合适的工具。用你最喜欢的语言(比如Python)来解析字符串。如果你对UDF持开放态度,我可能会为你提供一个解决方案,但是你需要以文本而不是图像的形式提供示例数据John先生。如何发送给您编辑您的问题并将上面所示的4行粘贴为文本OK,我在charIndex的子字符串(字符串,'净收入',字段长度)后添加了JohnAlso先生您可能想删除所有非数字100000+行,我如何插入@YourTable?@YohanDe the(at)YourTable只是一个用于说明/演示的表变量。@YohanDe使用外部应用如果您想看到NULLshow,我可以使用外部应用吗?我没用它before@YohanDe用外部应用程序替换交叉应用程序我的数据集有1000个确定值,如8600 4000 80000 6000,然后代码输出为8,4,80,6,如何修复此假设-每月交通服务净收入为55000/-费用20000/-净收入为30000/-我使用的是非CTE代码,它从上到下读取值,然后取净收入值55000。但这是错误的。我怎样才能得到30000英镑的净收入呢?你想让我找到最后一次出现的“净收入”并继续下去吗?或者你会提出什么样的解析建议?嗯,是的,尝试了各种方法来获取最后的净收入值。但是我做不到,可以吗
NetIncomes
------
86000
4000
80000
6000
86000