在两个已知字符串之间选择一个字符串的 SQL 查询

Posted

技术标签:

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

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

一个例子。

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

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

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

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

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

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

【问题讨论】:

您遇到了什么错误或返回了什么? "这条狗已经很糟糕了,不管怎样,都需要立即严厉惩罚" 【参考方案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

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

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

代码如下:

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)

【讨论】:

您能否添加更多关于您的查询正在做什么的解释,这将使您的答案更有帮助。欢迎使用 ***。【参考方案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

【讨论】:

以上是关于在两个已知字符串之间选择一个字符串的 SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

在两个动态(可变)日期 SQL 之间进行选择

使用正则表达式在两个日期之间进行 SQL 查询

删除 Hive SQL 查询中两个子字符串之间的所有字符

SQL查询选择年份在两个日期之间的行

SQL - 两个不同长度的字符串之间的相似性

在网页中的两个已知字符串之间提取文本并存储在变量中