Wie wähle ich einen Teilstring in Oracle SQL bis zu einem bestimmten Zeichen aus?


82

Angenommen, ich habe eine Tabellenspalte mit folgenden Ergebnissen:

ABC_blahblahblah
DEFGH_moreblahblahblah
IJKLMNOP_moremoremoremore

Ich möchte in der Lage sein, eine Abfrage zu schreiben, die diese Spalte aus dieser Tabelle auswählt, aber nur die Teilzeichenfolge bis zum Unterstrich (_) zurückgibt. Beispielsweise:

ABC
DEFGH
IJKLMNOP

Die SUBSTRING-Funktion scheint der Aufgabe nicht gewachsen zu sein, da sie positionsbasiert ist und die Position des Unterstrichs variiert.

Ich dachte über die TRIM-Funktion nach (speziell die RTRIM-Funktion):

SELECT RTRIM('listofchars' FROM somecolumn) 
FROM sometable

Aber ich bin mir nicht sicher, wie ich das zum Laufen bringen soll, da es nur eine bestimmte Liste / einen bestimmten Satz von Zeichen zu entfernen scheint und ich wirklich nur nach den Zeichen bin, die zum Unterstrich führen.

Antworten:


138

Wenn Sie eine Kombination aus SUBSTR, INSTR und NVL (für Zeichenfolgen ohne Unterstrich) verwenden, erhalten Sie das, was Sie möchten:

SELECT NVL(SUBSTR('ABC_blah', 0, INSTR('ABC_blah', '_')-1), 'ABC_blah') AS output
  FROM DUAL

Ergebnis:

output
------
ABC

Verwenden:

SELECT NVL(SUBSTR(t.column, 0, INSTR(t.column, '_')-1), t.column) AS output
  FROM YOUR_TABLE t

Referenz:

Nachtrag

Wenn Sie Oracle10g + verwenden, können Sie Regex über REGEXP_SUBSTR verwenden .


Vielen Dank. Sehr elegant! (Gut zu wissen über REGEXP_SUBSTR.) Ich habe nicht einmal daran gedacht, in Oracle nach Regex-Unterstützung zu suchen.
Brezel

In Oracle können Sie Funktionen (eigenständig oder in einem Paket) erstellen und in einer select-Anweisung verwenden.
Bart

9
Schlägt fehl, wenn Werte ausgeführt werden, die NICHT die gesuchte Teilzeichenfolge enthalten. instrGibt 0 zurück, wenn Sie haben INSTR('ABC/D', '_'). Am Ende haben Sie einen Teilstring von 0 bis (0-1), der null ist. Nicht gut.
Marcel Stör

39

Dies kann einfach mit REGEXP_SUBSTR erfolgen .

Benutzen Sie bitte

REGEXP_SUBSTR('STRING_EXAMPLE','[^_]+',1,1) 

Dabei ist STRING_EXAMPLE Ihre Zeichenfolge.

Versuchen:

SELECT 
REGEXP_SUBSTR('STRING_EXAMPLE','[^_]+',1,1) 
from dual

Es wird Ihr Problem lösen.


1
Ich stimme dem für die von OP gewählte Lösung zu, da es einen Trick macht. Es ist jedoch erwähnenswert, dass diese Lösung viel langsamer ist als die von @OMG Ponys, insbesondere wenn sie unter bestimmten Bedingungen verwendet wird. Meine Tests haben gezeigt, dass identische Abfragen etwa sechsmal langsamer ausgeführt werden. Diese Frage geht noch weiter auf das Thema stackoverflow.com/questions/41156391/…
Ister

In meinen Tests ist die INSTRLösung ungefähr genauso schnell wie die REGEXPLösung.
Alexander

7

Sie müssen die Position des ersten Unterstrichs (mit INSTR) ermitteln und dann den Teil des Strings mit substr vom ersten Zeichen bis (pos-1) abrufen.

  1  select 'ABC_blahblahblah' test_string,
  2         instr('ABC_blahblahblah','_',1,1) position_underscore,
  3         substr('ABC_blahblahblah',1,instr('ABC_blahblahblah','_',1,1)-1) result
  4*   from dual
SQL> /

TEST_STRING      POSITION_UNDERSCORE RES
---------------- ------------------  ---
ABC_blahblahblah                  4  ABC

Instr Dokumentation

Susbtr Dokumentation


6
SELECT REGEXP_SUBSTR('STRING_EXAMPLE','[^_]+',1,1)  from dual

ist die richtige Antwort, wie von user1717270 gepostet

Wenn Sie verwenden INSTR, erhalten Sie die Position für eine Zeichenfolge, die davon ausgeht, dass sie "_" enthält. Was ist, wenn es nicht so ist? Nun, die Antwort ist 0. Wenn Sie also die Zeichenfolge drucken möchten, wird a gedruckt NULL. Beispiel: Wenn Sie die Domain aus einer "host.domain" entfernen möchten. In einigen Fällen haben Sie nur den Kurznamen "Host". Höchstwahrscheinlich möchten Sie "Host" drucken. Nun, INSTRdamit erhalten Sie ein, NULLweil es kein "." Gefunden hat, dh es wird von 0 bis 0 gedruckt. Mit erhalten REGEXP_SUBSTRSie in allen Fällen die richtige Antwort:

SELECT REGEXP_SUBSTR('HOST.DOMAIN','[^.]+',1,1)  from dual;

GASTGEBER

und

SELECT REGEXP_SUBSTR('HOST','[^.]+',1,1)  from dual;

GASTGEBER



0

Denken Sie daran, wenn alle Ihre Zeichenfolgen in der Spalte keinen Unterstrich haben (... oder wenn der Nullwert die Ausgabe ist):

SELECT COALESCE
(SUBSTR("STRING_COLUMN" , 0, INSTR("STRING_COLUMN", '_')-1), 
"STRING_COLUMN") 
AS OUTPUT FROM DUAL

0

So finden Sie eine Unterzeichenfolge aus einer großen Zeichenfolge:

string_value:=('This is String,Please search string 'Ple');

Um den String 'Ple'von zu finden, String_valuekönnen wir wie folgt vorgehen:

select substr(string_value,instr(string_value,'Ple'),length('Ple')) from dual;

Sie finden Ergebnis: Ple


0

Falls die String-Position nicht festgelegt ist, können wir mit der folgenden Select-Anweisung die erwartete Ausgabe erhalten.

Tabellenstruktur ID VARCHAR2 (100 BYTE) CLIENT VARCHAR2 (4000 BYTE)

Daten-ID CLIENT
1001 {"clientId": "con-bjp", "clientName": "ABC", "providerId": "SBS"}
1002 {"IdType": "AccountNo", "Id": "XXXXXXXX3521", "ToPricingId": "XXXXXXXX3521", "clientId": "Test-Cust", "clientName": "MFX"}

Voraussetzung - Suchen Sie in der Spalte CLIENT nach der Zeichenfolge "ClientId" und geben Sie den entsprechenden Wert zurück. Wie von "clientId": "con-bjp" -> con-bjp (erwartete Ausgabe)

Wählen Sie CLIENT, substr (substr (CLIENT, instr (CLIENT, '"clientId": "') + length ('" clientId ":"')), 1, instr (substr (CLIENT, instr (CLIENT, '"clientId") : "') + Länge ('" clientId ":" ')),' "', 1) -1) cut_str von TEST_SC;

CLIENT cut_str ------------------------------------------------ ----------- ---------- {"clientId": "con-bjp", "clientName": "ABC", "providerId": "SBS"} con bjp {"IdType": "AccountNo", "Id": "XXXXXXXX3521", "ToPricingId": "XXXXXXXX3521", "clientId": "Test-Cust", "clientName": "MFX"} Test-Cust

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.