2016-12-13 2 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 

편집

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

메시지 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 같은. –

관련 문제