取空​​格和点之间的值

时间:2017-04-03 03:38:28

标签: sql sql-server tsql

我有这些字符串,

1. "Drs. H. Ahmad Malik S.Kom S.E S.pd"
2. "H. Ahmad Abdul Malik S.Kom S.E S.pd"

预期产出:

1. Ahmad Malik
2. Ahmad Abdul Malik

任何人都可以帮我解决它,我尝试使用substring,patindex但总是没有得到预期的输出

2 个答案:

答案 0 :(得分:0)

几乎任何解析/拆分函数都可以解决问题。

选项1具有解析/分割功能

Declare @YourTable table (ID int,Name varchar(100))
Insert Into @YourTable values
(1,'Drs. H. Ahmad Malik S.Kom S.E S.pd'),
(2,'H. Ahmad Abdul Malik S.Kom S.E S.pd')

Select A.*
      ,B.*
 From  @YourTable A
 Cross Apply (
              Select NewString = Stuff((Select  ' ' +RetVal 
                From [dbo].[udf-Str-Parse](A.Name,' ') 
                Where RetVal Not Like '%.%'
             Order by RetSeq
             For XML Path ('')),1,1,'')
  ) B

选项2没有解析/拆分功能

Select A.*
      ,B.*
 From  @YourTable A
 Cross Apply (
              Select NewString = Stuff((Select  ' ' +RetVal 
                From (
                        Select RetSeq = Row_Number() over (Order By (Select null))
                              ,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
                        From  (Select x = Cast('<x>' + replace((Select replace(A.Name,' ','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as A 
                        Cross Apply x.nodes('x') AS B(i)
                     ) B1
                Where RetVal Not Like '%.%'
             Order by RetSeq
             For XML Path ('')),1,1,'')
  ) B

返回

ID  Name                                  NewString
1   Drs. H. Ahmad Malik S.Kom S.E S.pd    Ahmad Malik 
2   H. Ahmad Abdul Malik S.Kom S.E S.pd   Ahmad Abdul Malik 

感兴趣的UDF

CREATE FUNCTION [dbo].[udf-Str-Parse] (@String varchar(max),@Delimiter varchar(25))
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 a,cte1 b,cte1 c,cte1 d) A ),
           cte3(N)   As (Select 1 Union All Select t.N+DataLength(@Delimiter) From cte2 t Where Substring(@String,t.N,DataLength(@Delimiter)) = @Delimiter),
           cte4(N,L) As (Select S.N,IsNull(NullIf(CharIndex(@Delimiter,@String,s.N),0)-S.N,8000) From cte3 S)

    Select RetSeq = Row_Number() over (Order By A.N)
          ,RetVal = LTrim(RTrim(Substring(@String, A.N, A.L)))
    From   cte4 A
);
--Orginal Source http://www.sqlservercentral.com/articles/Tally+Table/72993/
--Much faster than str-Parse, but limited to 8K
--Select * from [dbo].[udf-Str-Parse-8K]('Dog,Cat,House,Car',',')
--Select * from [dbo].[udf-Str-Parse-8K]('John||Cappelletti||was||here','||')

答案 1 :(得分:0)

更新了新信息

Declare @YourTable table (ID int,Name varchar(100))
Insert Into @YourTable values
(4,'Drs. H. Ahmad Malik A. N. S.Kom S.E S.pd'),
(1,'Drs. H. Ahmad Malik S.Kom S.E S.pd'),
(2,'H. Ahmad Abdul Malik S.Kom S.E S.pd'),
(3,'Drs. H. Ahmad Malik S.Kom S.E S.pd')

Select A.*
      ,C.*
 From  @YourTable A
 Cross Apply (Select * From [dbo].[udf-Str-Parse](A.Name,'S.Kom') Where RetSeq=1) B
 Cross Apply (
              Select NewString = Stuff((Select  ' ' +RetVal 
                                        From (
                                              Select *,Excl=min(Flag) over (Order By RetSeq)
                                               From (Select *,Flag=case when charindex('.',RetVal)>0 then 1 else 0 end From [dbo].[udf-Str-Parse](B.RetVal,' ') ) C1
                                             ) C2
                                        Where Excl=0
                                        Order by RetSeq
                                        For XML Path ('')),1,1,'')
             ) C

<强>返回

ID  Name                                        NewString
1   Drs. H. Ahmad Malik S.Kom S.E S.pd          Ahmad Malik
2   H. Ahmad Abdul Malik S.Kom S.E S.pd         Ahmad Abdul Malik
3   Drs. H. Ahmad Malik S.Kom S.E S.pd          Ahmad Malik
4   Drs. H. Ahmad Malik A. N. S.Kom S.E S.pd    Ahmad Malik A. N.   << Notice A. N.