2017-02-28 21 views
0

複数の文字を連続して複数回繰り返す複数の文字列を抽出する必要があります。例えば ; これらは私のテーブルから2行です:SQLサーバーで複数回繰り返される2文字の文字列を取得する

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

私の予想される結果は以下のとおりです。

id myString 
1 bb 
1 ddd 
2 ff 
2 hhh 

は、どのように私はそれを行うことができますか?

ありがとうございます。

答えて

1

一つの方法は、再帰CTEを使用しています。文字列は常に解決するために'..(..)' 1つの方法の繰り返しパターンを、以下の場合は

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

あなたのコードでは、 'CHARINDEX関数を上げている2〜3 arguments.' –

-1

回答のSQLServer 2016

DECLARE @t table(id int, myString varchar(40)) 
INSERT @t 
VALUES (1,'aaa(bb)ccc(ddd)'),(2, 'eeee(ff)gggg(hhh)iii') 

SELECT id, stuff(value, 1, charindex('(',value),'') myString 
FROM 
    @t t 
CROSS APPLY 
    STRING_SPLIT(mystring,')') 
WHERE value like '%(%' 
ORDER BY id 

Fiddle

+0

を必要とし、このクエリに対するBY提示順序を追加する理由はありませんテーブルの索引付け方法に応じて実行計画にソートが発生します。 –

+0

@AlanBurstein私はあなたと幼稚な戦争に行くことはありません。これは、[this](http://stackoverflow.com/questions/42698979/select-query-to-match-multiple-column-with-multiple-keywords/42703934#comment72534461_42703934)のため投票された素晴らしい回答です。これに関するインデックスは答えとは関係ありません。 –

+0

あなたの答えは上手です。実行計画のソートでは、インデックスを処理するためのインデックスがない場合はクエリの処理速度が低下します。パフォーマンスは常に重要です。記録のために、私はあなたの答えの投票を取り消そうとしましたが、答えることはできません。乾杯。 –

1

で動作しますこれは、Jeff ModenのCSVスプリッタ機能を使用して、2番目の区切り記号

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 

テストセットアップ:http://rextester.com/DAI48471

追加された例の入力戻り

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  | 
+----+----------+ 

分割ストリング参照modulo (%)を用いて第1のデリミタ、及び取得のみ第二の組と:

+0

これは素晴らしい解決策です。 '(()ab'や ')))ab)のような悪いデータの場合に問題があると思われます。ab - これは角かっこの中にないと考えてもabを返します –

+0

@ t-clausen.dkそれは本当です。私の答えの最初の行でそれを注意しようとしました "もし文字列が' ..(..) 'の繰り返しパターンに常に従っていれば、 – SqlZim

関連する問題