在两个字符串之间选择字符串

时间:2019-07-23 20:57:36

标签: sql sql-server

我需要在两个字符串之间输出一个字符串。问题是有时会丢失两个参考字符串之一。如果第一个参考字符串不丢失,而第二个参考字符串丢失,我想从第一个参考字符串输出到字符串末尾。如果缺少第一个参考字符串,我想输出null或空白。

我看到了类似的帖子,但其中包含了参考字符串。就我而言,我不想包含参考字符串。

SELECT SUBSTRING(@Text, CHARINDEX('1stRefStr', @Text)
, CHARINDEX('2ndRefStr',@text) - CHARINDEX('1stRefStr', @Text) + Len('2ndRefStr'))
Example:
Patient: A Date: 1/1/1 Message: Hi Message Sent To: B
1st string reference is "Message:"
2nd string reference is "Message Sent To:"
Expected Result:
Hi

1 个答案:

答案 0 :(得分:1)

如果您不介意辅助功能。

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

我修改了一个split / parse函数以接受两个非相似的距离计。

示例

Declare @Text varchar(max) = 'Patient: A Date: 1/1/1 Message: Hi Message Sent To: B'

Select *
 From  [dbo].[tvf-Str-Extract](@Text,'Message:','Message Sent') A

返回

RetSeq  RetVal
1       Hi 

功能

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

    Select RetSeq = row_number() over (order by RetSeq)
          ,RetVal = left(RetVal,charindex(@Delim2,RetVal)-1)
    From  (
            Select RetSeq = row_number() over (order by 1/0)
                  ,RetVal = ltrim(rtrim(B.i.value('(./text())[1]', 'varchar(max)')))
            From  ( values (convert(xml,'<x>' + replace((Select replace(@String,@Delim1,'§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>').query('.'))) as A(XMLData)
            Cross Apply XMLData.nodes('x') AS B(i)
          ) C1
    Where charindex(@Delim2,RetVal)>1
)

作为交叉申请书进行更新

Declare @YourTable table (ID int,SomeCol varchar(max))
Insert Into @YourTable values 
(1,'Patient: A Date: 1/1/1 Message: Hi Message Sent To: B')

Select A.ID
      ,B.*
 From  @YourTable A
 Cross Apply (
                Select RetSeq = row_number() over (order by RetSeq)
                      ,RetVal = left(RetVal,charindex('Message Sent',RetVal)-1)
                 From  (
                         Select RetSeq = row_number() over (order by 1/0)
                               ,RetVal = ltrim(rtrim(B.i.value('(./text())[1]', 'varchar(max)')))
                          From  ( values (convert(xml,'<x>' + replace((Select replace(SomeCol,'Message:','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>').query('.'))) as A(XMLData)
                          Cross Apply XMLData.nodes('x') AS B(i)
                       ) C1
                 Where charindex('Message Sent',RetVal)>1
             ) B