【问题标题】:A SQL Query to select a string between two known strings在两个已知字符串之间选择一个字符串的 SQL 查询
【发布时间】:2013-08-24 02:38:54
【问题描述】:

我需要一个 SQL 查询来获取两个已知字符串之间的值(返回的值应该以这两个字符串开头和结尾)。

一个例子。

“我只知道这只狗很坏,不管别人怎么想,都需要立即严厉惩罚。”

在这种情况下,已知的字符串是“the dog”和“immediately”。所以我的查询应该返回“这只狗非常糟糕,需要立即严厉惩罚”

到目前为止我已经想出了这个,但无济于事:

SELECT SUBSTRING(@Text, CHARINDEX('the dog', @Text), CHARINDEX('immediately', @Text))

@Text 是包含主字符串的变量。

有人可以帮我解决我哪里出错了吗?

【问题讨论】:

  • 您遇到了什么错误或返回了什么?
  • "这条狗已经很糟糕了,不管怎样,都需要立即严厉惩罚"

标签: sql sql-server substring


【解决方案1】:

问题在于子字符串参数的第二部分包含第一个索引。 您需要从第二个索引中减去第一个索引才能使这项工作正常进行。

SELECT SUBSTRING(@Text, CHARINDEX('the dog', @Text)
, CHARINDEX('immediately',@text) - CHARINDEX('the dog', @Text) + Len('immediately'))

【讨论】:

  • 如果您要查找的书挡每个仅出现一次,则此方法有效,但如果它们出现多次则无效。
【解决方案2】:

一个例子是这样的:你有一个字符串和字符 $

字符串

aaaaa$bbbbb$ccccc

代码

SELECT SUBSTRING('aaaaa$bbbbb$ccccc',CHARINDEX('$','aaaaa$bbbbb$ccccc')+1, CHARINDEX('$','aaaaa$bbbbb$ccccc',CHARINDEX('$','aaaaa$bbbbb$ccccc')+1) -CHARINDEX('$','aaaaa$bbbbb$ccccc')-1) as My_String

输出

bbbbb

【讨论】:

  • 如果你有类似'aaaaa$bbbbb$cc$ccc$' 的东西并且你希望它返回包含bbbbb & ccc 的两行?
  • 对于第一行,我提供的选择没问题。对于第二个 (aaaaa$bbbbb$cc$ccc) :选择 reverse(left(reverse('aaaaa$bbbbb$cc$ccc'), charindex('$', reverse('aaaaa$bbbbb$cc$ccc') ) -1))
  • 这并不能真正回答问题,因为它假定 OPs 字符串的“书挡”是相同的字符,这是不正确的。
【解决方案3】:

我认为埃文的意思是这样的:

SELECT SUBSTRING(@Text, CHARINDEX(@First, @Text) + LEN(@First), 
                 CHARINDEX(@Second, @Text) - CHARINDEX(@First, @Text) - LEN(@First))

【讨论】:

  • 不完全是OP所要求的:这个答案剥离了边缘的字符串。但这是一个有用的 sn-p。
【解决方案4】:

我也需要解析出存储在 IIS 日志的 csUriQuery 字段中的一组参数,如下所示:this format 中需要id=3598308&user=AD\user&parameter=1&listing=No

我最终创建了一个用户定义的函数来完成一个字符串之间的关系,假设如下:

  1. 如果没有找到起始事件,则返回NULL,并且
  2. 如果未找到结尾出现,则返回字符串的其余部分

代码如下:

CREATE FUNCTION dbo.str_between(@col varchar(max), @start varchar(50), @end varchar(50))  
  RETURNS varchar(max)  
  WITH EXECUTE AS CALLER  
AS  
BEGIN  
  RETURN substring(@col, charindex(@start, @col) + len(@start), 
         isnull(nullif(charindex(@end, stuff(@col, 1, charindex(@start, @col)-1, '')),0),
         len(stuff(@col, 1, charindex(@start, @col)-1, ''))+1) - len(@start)-1);
END;  
GO

对于上面的问题,用法如下:

DECLARE @a VARCHAR(MAX) = 'All I knew was that the dog had been very bad and required harsh punishment immediately regardless of what anyone else thought.'
SELECT dbo.str_between(@a, 'the dog', 'immediately')
-- Yields' had been very bad and required harsh punishment '

【讨论】:

  • 我喜欢这个解决方案。如果您传递 CHAR(xx) 控制字符(如 NEWLINE 和 CARRIAGE RETURN),它甚至可以工作
  • 这个函数是
【解决方案5】:

您需要调整 SUBSTRING 中的 LENGTH。您将其指向“结束字符串”的 END。

试试这样的:

declare @TEXT varchar(200)
declare @ST varchar(200)
declare @EN varchar(200)
set @ST = 'the dog'
set @EN = 'immediately'
set @TEXT = 'All I knew was that the dog had been very bad and required harsh punishment immediately regardless of what anyone else thought.'
SELECT SUBSTRING(@Text, CHARINDEX(@ST, @Text), (CHARINDEX(@EN, @Text)+LEN(@EN))-CHARINDEX(@ST, @Text))

当然,你可能需要稍微调整一下。

【讨论】:

    【解决方案6】:

    试试这个并用你的字符串替换 '[' & ']'

    SELECT SUBSTRING(@TEXT,CHARINDEX('[',@TEXT)+1,(CHARINDEX(']',@TEXT)-CHARINDEX('[',@TEXT))-1)
    

    【讨论】:

      【解决方案7】:

      我感觉您可能需要 SQL Server 的 PATINDEX() 函数。看看这个:

      Usage on Patindex() function

      所以也许:

      SELECT SUBSTRING(@TEXT, PATINDEX('%the dog%', @TEXT), PATINDEX('%immediately%',@TEXT))
      

      【讨论】:

        【解决方案8】:
        SELECT 
        SUBSTRING( '123@yahoo.com',  charindex('@','123@yahoo.com',1) + 1, charindex('.','123@yahoo.com',1) - charindex('@','123@yahoo.com',1) - 1 )
        

        【讨论】:

          【解决方案9】:
          DECLARE @Text VARCHAR(MAX), @First VARCHAR(MAX), @Second VARCHAR(MAX)
          SET @Text = 'All I knew was that the dog had been very bad and required harsh punishment immediately regardless of what anyone else thought.'
          SET @First = 'the dog'
          SET @Second = 'immediately'
          
          SELECT SUBSTRING(@Text, CHARINDEX(@First, @Text), 
                           CHARINDEX(@Second, @Text) - CHARINDEX(@First, @Text) + LEN(@Second))
          

          【讨论】:

            【解决方案10】:

            您将获得“立即惩罚”的起始位置,但将其作为子字符串的长度参数传递。

            您需要从“立即惩罚”的 charindex 中减去“狗”的起始位置,然后将“立即惩罚”字符串的长度添加到您的第三个参数。这将为您提供正确的文本。

            这里有一些粗略的、hacky 的代码来说明这个过程:

            DECLARE @text VARCHAR(MAX)
            SET @text = 'All I knew was that the dog had been very bad and required harsh punishment immediately regardless of what anyone else thought.'
            
            DECLARE @start INT
            SELECT @start = CHARINDEX('the dog',@text)
            
            DECLARE @endLen INT
            SELECT @endLen = LEN('immediately')
            
            DECLARE @end INT
            SELECT @end = CHARINDEX('immediately',@text)
            SET @end = @end - @start + @endLen
            
            SELECT @end
            
            SELECT SUBSTRING(@text,@start,@end)
            

            结果:狗已经很坏了,需要立即严厉惩罚

            【讨论】:

              【解决方案11】:
              <pre>
              

              声明@text VARCHAR(MAX)

              SET @text = 'All I knew was that the dog had been very bad and required harsh punishment immediately regardless of what anyone else thought.'
              
              declare @pretext as nvarchar(100) = 'the dog'    
              declare @posttext as nvarchar(100) = 'immediately'
              
              SELECT 
               CASE 
              When CHARINDEX(@posttext, @Text) - (CHARINDEX(@pretext, @Text) + len(@pretext)) < 0 THEN 
              ''
              Else
              SUBSTRING(@Text, CHARINDEX(@pretext, @Text) + len(@pretext)
              ,   CHARINDEX(@posttext, @Text) - (CHARINDEX(@pretext, @Text) + len(@pretext)) )    
              END as betweentext  
              

              【讨论】:

              • 虽然欢迎使用此代码 sn-p,并且可能会提供一些帮助,但它会是 greatly improved if it included an explanation of howwhy 这解决了问题。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人!请edit您的答案添加解释,并说明适用的限制和假设。
              【解决方案12】:
              SELECT SUBSTRING('aaaaa$bbbbb$ccccc',instr('aaaaa$bbbbb$ccccc','$',1,1)+1, instr('aaaaa$bbbbb$ccccc','$',1,2)-1) -instr('aaaaa$bbbbb$ccccc','$',1,1)) as My_String
              

              【讨论】:

                【解决方案13】:

                希望这会有所帮助: 声明了一个变量,如果有任何更改只需要进行一次。

                declare @line  varchar(100)
                
                set @line ='Email_i-Julie@mail.com'
                
                select SUBSTRING(@line ,(charindex('-',@line)+1), CHARINDEX('@',@line)-charindex('-',@line)-1)
                

                【讨论】:

                • 您能否添加更多关于您的查询正在做什么的解释,这将使您的答案更有帮助。欢迎使用 StackOverflow。
                【解决方案14】:
                select substring(@string,charindex('@first',@string)+1,charindex('@second',@string)-(charindex('@first',@string)+1))
                

                【讨论】:

                • 考虑添加几句话来解释问题中的错误。
                【解决方案15】:

                假设我们有一个字符串DUMMY_DATA_CODE_FILE,我们想找出第二个和第三个下划线(_)之间的子字符串。然后我们使用类似这样的查询。

                select  SUBSTRING('DUMMY_DATA_CODE_FILE',charindex('_', 'DUMMY_DATA_CODE_FILE', (charindex('_','DUMMY_DATA_CODE_FILE', 1))+1)+1, (charindex('_', 'DUMMY_DATA_CODE_FILE', (charindex('_','DUMMY_DATA_CODE_FILE',  (charindex('_','DUMMY_DATA_CODE_FILE', 1))+1))+1)- charindex('_', 'DUMMY_DATA_CODE_FILE', (charindex('_','DUMMY_DATA_CODE_FILE', 1))+1)-1)) as Code
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2018-06-24
                  • 2015-09-20
                  • 1970-01-01
                  • 2011-01-30
                  • 1970-01-01
                  • 2020-11-13
                  • 1970-01-01
                  • 2013-07-25
                  相关资源
                  最近更新 更多