【问题标题】:SQL Query to get a substring between [ ] in a string with multiple parenthesesSQL 查询以获取具有多个括号的字符串中 [ ] 之间的子字符串
【发布时间】:2017-02-26 17:38:21
【问题描述】:

我有一个名为“公式”的文本字符串列,其中变量用 ID 编码并设置在括号中,括号中的文本长度可以变化,这种括号的数量实际上是无限的。数据示例:

  • [a=5;b=1;c=15]
  • [x=1;a=5;b=1;c=15]*[a=4;c=2]
  • =IF([a=10232937;c=227634]=1;[a=2;b=51;d=14]*[a=1;b=51;d=14];0)

我寻找a 和c 的特定组合,比如:

Select Formula FROM Table WHERE Formula LIKE "%a=5%c=2%"

结果将是[x=1;a=5;b=1;c=15]*[a=4;c=2],尽管在这种情况下a=5 和c=2 位于不同的括号中,并且所需的结果实际上是一个空值。

关于如何在任何给定括号内查找的任何想法?

UPD:这是 SQL Server 2014

【问题讨论】:

  • UPD:这是 SQL Server 2014
  • 你能解释一下为什么“%a=5%c=2%”没有给你想要的吗?只有在某个括号 [] 内时才需要它吗?
  • 解决这个问题的绝对最佳方法是停止在数据库中存储分隔值。这违反了 1NF,处理起来非常痛苦。如果您有一个字符串拆分器,您可以在“]”上拆分它,然后在每个解析集中查找是否存在。这里有几个优秀的分离器。 sqlperformance.com/2012/07/t-sql-queries/split-strings
  • 找到一个 TSQL 拆分函数

标签: sql sql-server substring


【解决方案1】:

假设变量总是带有方括号。下面的代码在a=5和c=2之间检查[和]。

declare @table table
(
Formula varchar(max)
)

Insert into @table values ('[x=1;a=5;b=1;c=15]*[a=4;c=2]');
Insert into @table values ('[x=1;a=5;b=1;c=15;a=4;c=2]');

declare @search1 varchar(100) = 'a=5'
declare @search2 varchar(100) = 'c=2'

SELECT Formula
FROM (
Select Formula
, CHARINDEX('[', (SUBSTRING(Formula, CHARINDEX(@search1, Formula), CHARINDEX(@search2, Formula) - CHARINDEX(@search1, Formula)))) LeftPar
, CHARINDEX(']', (SUBSTRING(Formula, CHARINDEX(@search1, Formula), CHARINDEX(@search2, Formula) - CHARINDEX(@search1, Formula)))) RightPar
from @table
WHERE Formula like '%\[%\]%' ESCAPE '\'
) x
Where LeftPar = 0 AND RightPar = 0

--Output
--[x=1;a=5;b=1;c=15;a=4;c=2]

【讨论】:

  • 谢谢,但不幸的是,查询在子字符串或左/右参数中返回错误
  • 我没有收到任何错误,使用示例数据更新了查询。请运行并验证。
  • 我想这里有一个假设,即在括号 ] 之前总是有 c=NUM。实际上 c=NUM 也可以位于中间
  • [a=4;c=5;b=1]*[a=6;c=4;b=1]
【解决方案2】:

一个简单的 Parse/Split 函数可以提供帮助

Declare @YourTable table (ID int, Formula varchar(max))
Insert Into @YourTable values
(1,'[a=5;b=1;c=15]'),
(2,'[x=1;a=5;b=1;c=15]*[a=4;c=2]'),
(3,'=IF([a=10232937;c=227634]=1;[a=2;b=51;d=14]*[a=1;b=51;d=14];0')

Select Distinct A.*
 From  @YourTable A
 Cross Apply [dbo].[udf-Str-Parse](A.Formula,']')  B
 Where RetVal Like '%a=5%c=2%'

不返回任何数据

同时 Where RetVal Like '%a=1%c=2%'

退货

ID  Formula
3   =IF([a=10232937;c=227634]=1;[a=2;b=51;d=14]*[a=1;b=51;d=14];0

如果需要,UDF(如果您不能使用 UDF,也可以将逻辑移植到交叉应用中)

CREATE FUNCTION [dbo].[udf-Str-Parse] (@String varchar(max),@Delimiter varchar(10))
Returns Table 
As
Return (  
    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(@String,@Delimiter,'</x><x>')+'</x>' as xml).query('.')) as A 
    Cross Apply x.nodes('x') AS B(i)
);

【讨论】:

  • 这很好用,谢谢!您是否也知道字符串的解决方案,其中一些括号插入到其他括号中_
  • 我的意思是这样的数据:[a=5;b=[a=4;b=1;c=2];c=15]
  • @WhereVit 抱歉,此解决方案不会捕获嵌套的 []。我会多加一点。
猜你喜欢
  • 2016-03-24
  • 2016-08-30
  • 1970-01-01
  • 2022-08-03
  • 1970-01-01
  • 1970-01-01
  • 2013-02-04
  • 2016-01-26
  • 1970-01-01
相关资源
最近更新 更多