在两个已知字符串之间选择一个字符串的 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 how 和 why 这解决了问题。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人!请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 查询的主要内容,如果未能解决你的问题,请参考以下文章