2016-12-13 6 views
1

Ich habe eine Spalte mit Variablennamen wieExtrahieren Sie Text aus einer Zeichenfolge, die von der Zeichenfolge "Righ" (keine Zeichenfolge) ausgeht. SQL

UB121216SVC0054 
12122016TH10076 
UB121216OH10058 

Ich möchte die Briefe extrahieren von rechts nach links.

Da die Anzahl der Buchstaben und Zahlen variiert, kann ich keine Teilzeichenfolge verwenden, um das erste und letzte Zeichen anzugeben.

Wie kann ich darüber gehen?

+0

Können Sie genauer? – Teja

+0

Was ist das genaue Muster? Ist es "Nummer/Zeichen .. SVC .. Zahlen"? Beenden sie immer mit Zahlen? –

+0

Es endet immer mit Zahlen, etwas mit umgekehrten und Standard finden Sie den Buchstaben +2? – gizq

Antwort

1

Dies funktioniert für alle Ihre Testfälle ... Es schneidet zunächst alle nachgestellten Ziffern und dann nur die Zeichenketten vor, bis eine Ziffer gefunden wird. Ändern Sie die Variable @var in einen beliebigen Ihrer Testfälle.

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

Gleiches Problem von Msg 536, Ebene 16, Status 2, Zeile 3 Ungültiger Längenparameter, der an die RIGHT-Funktion übergeben wurde. – gizq

+0

Was haben Sie versucht, an die var @ gizq zu übergeben? – scsimon

+0

@ gizq das wird passieren, wenn Sie keine Buchstaben in der Mitte haben, wie UH234534254325 – scsimon

0

Für die Beispiele, die Sie geben, scheint der folgende Code wie eine einfache genug Lösung:

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

Dies wird unter der Annahme, dass die Codes sind 2- oder 3-Zeichen und immer an der neunten Position starten.

+0

Es funktioniert ordnungsgemäß, aber die Teilzeichenfolge beginnt nicht immer bei Position 9 – gizq

0

Beachten Sie, dass diese Version den gleichen grundlegenden Ausführungsplan als Radu Code (oben) erstellt, aber ich finde es viel besser lesbar zu sein. Kommentare enthalten.

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

Hinweis: Ich testete dies mit einer Tabelle mit zusätzlichen Feldern und 90k + Zeilen und sogar die zusätzlichen Felder, den Plan und die Ausführungszeit ar zurückgeben e das gleiche. –

Verwandte Themen