获取2个字符之间的字符串,在sql server中重复多次

时间:2017-02-28 12:40:14

标签: sql-server string function

我需要在两个特定字符之间提取多个字符串,这些字符连续多次重复。 例如; 这些是我表中的两行:

id myString
1 'aaa(bb)ccc(ddd)'
2 'eeee(ff)gggg(hhh)iii'

我的预期结果是:

id myString
1  bb
1  ddd
2  ff
2  hhh

我该怎么做?

提前致谢。

4 个答案:

答案 0 :(得分:1)

一种方法使用递归CTE:

with cte as (
      select id,
             left(stuff(myString, 1, charindex('(', myString), ''),
                  charindex(')', myString) - charindex('(', myString) - 1
                 ) as val,
             stuff(myString, 1, charindex(')', myString) + 1) as rest
      from t
      where myString like '%(%)%'
      union all
      select id,
             left(stuff(rest, 1, charindex('(', rest), ''),
                  charindex(')', rest) - charindex('(', rest) - 1
                 ) as val,
             stuff(rest, 1, charindex(')', myString) + 1) as rest
      from cte
      where rest like '%(%)%'
     )
select id, val
from cte;

答案 1 :(得分:1)

如果字符串始终遵循'..(..)'的重复模式,则解决此问题的一种方法使用Jeff Moden的CSV分割器函数,用第一个分隔符替换第二个分隔符,并使用{{3获取第二个分隔符}}:

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

测试设置:modulo (%)

添加了3,'jjj(kkk)ll(mmm)n(ooooo)pp(qq)rr'

的示例输入

返回:

+----+----------+
| Id | myString |
+----+----------+
|  1 | bb       |
|  1 | ddd      |
|  2 | ff       |
|  2 | hhh      |
|  3 | kkk      |
|  3 | mmm      |
|  3 | ooooo    |
|  3 | qq       |
+----+----------+

拆分字符串参考:

答案 2 :(得分:1)

我知道我来晚了很晚,但是遇到了一个完全相同的问题,并找到了一种非常简便的方法来递归CTE。

我希望这对遇到相同问题的人有所帮助。

IF OBJECT_ID('tempdb..#Temp') IS NOT NULL DROP TABLE #Temp
CREATE TABLE #Temp (
    [ID]    INT,
    [Text]  VARCHAR(255)
)

INSERT INTO #Temp ([ID], [Text])
VALUES (1, '(test1) sdkjsdlfnicsn */12e3mdsf ksd (test 2) $#@ewmfdsdk (test3)'), (2, '(test4) sdvdsg */sdg ksd (test 5) $#@ewmfdsdk (test6)(test7)')

;WITH CTE AS (
    SELECT [x].[ID], [x].[Text], [x].[OpenBraket], [x].[CloseBraket]
    ,SUBSTRING([x].[Text], ([x].[OpenBraket] + 1), ([x].[CloseBraket] - [x].[OpenBraket] - 1)) AS [Value]
    ,SUBSTRING([x].[Text], ([x].[CloseBraket] + 1), (LEN([Text]) - [x].[CloseBraket])) AS [RemainingText]
    FROM (
        SELECT [ID], [Text]
            ,CHARINDEX('(', [Text]) AS [OpenBraket]
            ,CHARINDEX(')', [Text]) AS [CloseBraket]        
        FROM #Temp
        WHERE [Text] LIKE '%(%)%'
    ) x

    UNION ALL

    SELECT [z].[ID], [z].[Text], [z].[OpenBraket], [z].[CloseBraket]
        ,SUBSTRING([z].[RemainingText], ([z].[OpenBraket] + 1), ([z].[CloseBraket] - [z].[OpenBraket] - 1)) AS [Value]
        ,SUBSTRING([z].[RemainingText], ([z].[CloseBraket] + 1), (LEN([RemainingText]) - [z].[CloseBraket])) AS [RemainingText]
    FROM (
        SELECT [ID], [Text], [RemainingText]
            ,CHARINDEX('(', [RemainingText]) AS [OpenBraket]
            ,CHARINDEX(')', [RemainingText]) AS [CloseBraket]
        FROM [CTE]
        WHERE [RemainingText] LIKE '%(%)%'
    ) z
)

SELECT [ID], [Value] FROM CTE

答案 3 :(得分:-1)

答案适用于sqlserver 2016

private TabItem _currentTabItem;
public TabItem CurrentTabItem 
                 {
                     get {return _currentTabItem;} 
                     set
                         {
                           if(_currentTabItem == value) return;
                            _currentTabItem = value;
                            OnPropertyChanged(nameOf(CurrentTabItem);
                          }
                   }

<强> Fiddle