2017-02-28 72 views
0

我有这样的数据: -如何从SQL消息中查找子字符串?

1)您指定的运营商是{carrier_name}。他们会尽快与您联系以安排接机,但请随时致电{carrier_phone}并参考{reference_id}。他们现在开放,直到{close_time}。

2){vehicle_owner}表示他们的{body_style}被拾起。你会提供一份关于任务的更新或者标记完成吗?

我想查找括号内的所有值 - >{___}

只应在括号内找到特定的消息。他们之间可能有任何价值。

如何使用查询找出它?

+0

添加一些示例表格数据和预期结果 - 以及格式化文本。同时向我们展示您当前的查询尝试。 – jarlh

+0

这是格式化的data.Here,1是id和2是消息。 @jarlh –

回答

2

如果字符串总是跟随'..{..})'一个方法的重复图案来解决这个使用由Jeff MODEN一个CSV分配器功能,与第一分隔符替换第二分隔符,且只得到使用modulo (%)所述第二组:

select 
    Id 
, col = x.item 
from t 
    cross apply (
    select Item = ltrim(rtrim(i.Item)) 
     from [dbo].[delimitedsplit8K](replace(t.col,'}','{'),'{') as i 
     where ItemNumber%2=0 
    ) x 

测试设置:http://rextester.com/VDBK82975

回报:

+----+---------------+ 
| Id |  col  | 
+----+---------------+ 
| 1 | carrier_name | 
| 1 | carrier_phone | 
| 1 | reference_id | 
| 1 | close_time | 
| 2 | vehicle_owner | 
| 2 | body_style | 
+----+---------------+ 

分割字符串引用:在测试中使用


功能:

create function [dbo].[delimitedsplit8K] (
     @pstring varchar(8000) 
    , @pdelimiter char(1) 
) 
returns table with schemabinding as 
return 
    with e1(N) as (
    select 1 union all select 1 union all select 1 union all 
    select 1 union all select 1 union all select 1 union all 
    select 1 union all select 1 union all select 1 union all select 1 
) 
    , e2(N) as (select 1 from e1 a, e1 b) 
    , e4(N) as (select 1 from e2 a, e2 b) 
    , ctetally(N) as (
    select top (isnull(datalength(@pstring),0)) 
     row_number() over (order by (select null)) from e4 
) 
    , ctestart(N1) as (
    select 1 union all 
    select t.N+1 from ctetally t where substring(@pstring,t.N,1) = @pdelimiter 
) 
    , ctelen(N1,L1) as (
    select s.N1, 
     isnull(nullif(charindex(@pdelimiter,@pstring,s.N1),0)-s.N1,8000) 
    from ctestart s 
) 
select itemnumber = row_number() over(order by l.N1) 
     , item  = substring(@pstring, l.N1, l.L1) 
    from ctelen l 
; 

递归CTE版本(不需要额外的功能)

;with cte as (
    select 
     id 
    , val = left(stuff(col, 1, charindex('{', col),'') 
       , charindex('}', col) - charindex('{', col) - 1 
      ) 
    , rest = stuff(col, 1, charindex('}', col) + 1,'') 
    from t 
    where col like '%{%}%' 
    union all 
    select 
     id 
    , val = left(stuff(rest, 1, charindex('{', rest),'') 
       , charindex('}', rest) - charindex('{', rest) - 1 
      ) 
    , rest = stuff(rest, 1, charindex('}', rest) + 1,'') 
    from cte 
    where rest like '%{%}%' 
) 
select id, val 
from cte 
order by id, val; 

回报:

+----+---------------+ 
| Id |  col  | 
+----+---------------+ 
| 1 | carrier_name | 
| 1 | carrier_phone | 
| 1 | reference_id | 
| 1 | close_time | 
| 2 | vehicle_owner | 
| 2 | body_style | 
+----+---------------+ 
+0

哇,这很快,很好的工作 – Tanner

+0

不工作。 我的表名是[Tbl_BotMessageLibrary],列是[Id]和[Message]。 此查询将在数据库上触发。 –

+0

对于这个答案,您需要创建用于分割值的函数。该函数在第一个参考中,在rextester测试链接中,现在也在答案的底部。 – SqlZim

-1

这可以通过SUBSTRINGCHARINDEX来实现

SUBSTRING(@Text, CHARINDEX('%{%',@Text), CHARINDEX('%}%',@Text)) 

CHARINDEX给出搜索字符串的第一次出现的值。在SUBSTRING中提供这些值,您可以获得所需的输出。

相关问题