2016-12-13 11 views
1

は、私はそのような文字列から部分文字なしの文字列を抽出します。 SQL

UB121216SVC0054 
12122016TH10076 
UB121216OH10058 

として変数名私は右から始まる文字を抽出したいを含む列を持っています。

SVC 
TH 
OH 

文字と数字の数が異なるため、部分文字列を使用して最初と最後の文字を指定することはできません。

どうすればこの問題を解決できますか?あなたが与える例について

+0

もっと具体的にすることはできますか? – Teja

+0

正確なパターンは何ですか?それは '数字/文字.. SVC ..数字'ですか?彼らはいつも数字で終わりますか? –

+0

いつも数字で終わり、逆のものと標準的な検索文字+2で何かをしていますか? – gizq

答えて

1

これは、すべてのテストケースで機能します... 最初にすべての末尾の数字をトリムし、その後に数字が見つかるまでそれより前の文字をサブストリングのみにします。 @varをテストケースに変更します。このバージョンでは、(上記)ラドゥのコードと同じ基本的な実行計画を作成しますが、私はそれがはるかに読みやすくするために見つけること

declare @var varchar(50) = ' ' 

select case when @var is not null and @var <> '' then 
     right(reverse(substring(reverse(@var),PATINDEX('%[^0-9]%',reverse(@var)),len(@var) - PATINDEX('%[^0-9]%',reverse(@var)))),PATINDEX('%[0-9]%',reverse(reverse(substring(reverse(@var),PATINDEX('%[^0-9]%',reverse(@var)),len(@var) - PATINDEX('%[^0-9]%',reverse(@var)))))) - 1) 
     else null end 

EDIT

declare @var varchar(50) = 'claim_ud H4748sd115600' 

select case 
     when @var is not null and @var <> '' then 
      case 
       when PATINDEX('% %',@var) = 0 then 
       right(reverse(substring(reverse(@var),PATINDEX('%[^0-9]%',reverse(@var)),len(@var) - PATINDEX('%[^0-9]%',reverse(@var)))),PATINDEX('%[0-9]%',reverse(reverse(substring(reverse(@var),PATINDEX('%[^0-9]%',reverse(@var)),len(@var) - PATINDEX('%[^0-9]%',reverse(@var)))))) - 1) 
       else 
       right(reverse(substring(reverse(stuff(@var,PATINDEX('% %',@var),PATINDEX('% %',reverse(@var)) - PATINDEX('% %',@var),1)),PATINDEX('%[^0-9]%',reverse(stuff(@var,PATINDEX('% %',@var),PATINDEX('% %',reverse(@var)) - PATINDEX('% %',@var),1))),len(stuff(@var,PATINDEX('% %',@var),PATINDEX('% %',reverse(@var)) - PATINDEX('% %',@var),1)) - PATINDEX('%[^0-9]%',reverse(stuff(@var,PATINDEX('% %',@var),PATINDEX('% %',reverse(@var)) - PATINDEX('% %',@var),1))))),PATINDEX('%[0-9]%',reverse(reverse(substring(reverse(stuff(@var,PATINDEX('% %',@var),PATINDEX('% %',reverse(@var)) - PATINDEX('% %',@var),1)),PATINDEX('%[^0-9]%',reverse(stuff(@var,PATINDEX('% %',@var),PATINDEX('% %',reverse(@var)) - PATINDEX('% %',@var),1))),len(stuff(@var,PATINDEX('% %',@var),PATINDEX('% %',reverse(@var)) - PATINDEX('% %',@var),1)) - PATINDEX('%[^0-9]%',reverse(stuff(@var,PATINDEX('% %',@var),PATINDEX('% %',reverse(@var)) - PATINDEX('% %',@var),1))))))) - 1) 
       end 
     else null end 
+0

Msg 536、レベル16、状態2、行3の同じ問題 RIGHT関数に無効な長さパラメータが渡されました。 – gizq

+0

何を試してvar @ gizqに渡しましたか? – scsimon

+0

@ gizqこれは、中間に「UH234534254325 – scsimon

0

は、次のコードは、単純な十分な解決策のように思える:これはコードが2位もしくは3文字であり、常に9番目の位置で開始することを想定している

select (case when substring(col, 11, 1) between '0' and '9' 
      then substring(col, 9, 2) 
      else substring(col, 9, 3) 
     end) 

+0

正常に動作しますが、部分文字列が常にpos 9で始まるとは限りません – gizq

0

注意。コメントが含まれています。

-- Create a testing table 
CREATE TABLE #codes (code varchar(32)) 
GO 
INSERT INTO #codes Values ('UB121216SVC0054') 
INSERT INTO #codes Values ('12122016TH10076') 
INSERT INTO #codes Values ('UB121216OH10058') 
GO 
-- Get the substring data 
SELECT -- Get the data up to the first non-letter 
    Reverse(LEFT(fragment, patindex('%[^A-Za-z]%', fragment)-1)) as substr 
FROM ( -- trim the field at the first letter 
    SELECT SUBSTRING(rcode, patindex('%[A-Za-z]%', rcode), len(rcode)) as fragment 
    FROM ( -- Working with the reversed values 
     SELECT reverse(code) as rcode 
     FROM #codes 
     ) as ReverseTable 
    ) as WorkTable 
+0

注:追加フィールドと90k +行、さらに追加のフィールドを返す場合でも、プランと実行時間ar同じ。 –

関連する問題