Oracle SQLで特定の文字までの部分文字列を選択するにはどうすればよいですか?


82

次のような結果を持つテーブル列があるとします。

ABC_blahblahblah
DEFGH_moreblahblahblah
IJKLMNOP_moremoremoremore

上記のテーブルからこの列を選択するクエリを記述できるようにしたいのですが、アンダースコア(_)文字までの部分文字列のみを返します。例えば:

ABC
DEFGH
IJKLMNOP

SUBSTRING関数は位置ベースであり、アンダースコアの位置が異なるため、タスクに対応していないようです。

私はTRIM関数(具体的にはRTRIM関数)について考えました:

SELECT RTRIM('listofchars' FROM somecolumn) 
FROM sometable

しかし、これがどのように機能するかはわかりません。これは、特定のリスト/文字セットを削除するだけのようであり、実際には、アンダースコア文字に至るまでの文字を追跡しているだけだからです。

回答:


141

SUBSTR、INSTR、およびNVL(アンダースコアのない文字列の場合)を組み合わせて使用​​すると、必要なものが返されます。

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

結果:

output
------
ABC

使用する:

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

参照:

補遺

Oracle10g +を使用している場合は、REGEXP_SUBSTRを介して正規表現を使用できます。


ありがとう。とてもエレガント!(REGEXP_SUBSTRについても知っておくとよいでしょう。)Oracleで正規表現のサポートを探すことすら考えていませんでした。
プレッツェル2010

Oracleでは、関数(スタンドアロンまたはパッケージ)を作成し、selectステートメントで使用できます。
バート2010

9
探している部分文字列を含まない値に対して実行すると失敗します。instrがある場合は0を返しますINSTR('ABC/D', '_')。最後に、0から(0-1)までの部分文字列があります。これはnullです。良くない。
マルセルSTOR

39

これは、REGEXP_SUBSTRを使用して簡単に実行できます。

使ってください

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

ここで、STRING_EXAMPLEは文字列です。

試してみてください:

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

それはあなたの問題を解決します。


1
それはトリックを行うので、私はOPによって選択されたソリューションに沿ってこれを支持しています。ただし、このソリューションは、@ OMG Poniesのソリューションよりもはるかに遅いことに注意してください。特に、このソリューションを使用する場合はなおさらです。私のテストでは、同じクエリの実行が約6倍遅いことが示されています。この質問は、トピックstackoverflow.com/questions/41156391/…
Ister 2018

私のテストでは、INSTRソリューションはソリューションとほぼ同じ速度で実行されREGEXPます。
alexherm

7

(INSTRを使用して)最初のアンダースコアの位置を取得してから、substrを使用して1番目の文字から(pos-1)までの文字列の一部を取得する必要があります。

  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ドキュメント

Susbtrドキュメント


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

user1717270によって投稿されたように、正解です

を使用するとINSTR、「_」が含まれていると想定される文字列の位置がわかります。そうでない場合はどうなりますか?答えは0になります。したがって、文字列を出力する場合は、を出力しNULLます。例:「host.domain」からドメインを削除する場合。場合によっては、「ホスト」などの短い名前しかありません。ほとんどの場合、「ホスト」を印刷したいと思うでしょう。さて、とINSTR、それはあなたを与えるだろうNULL「」で、それはいずれかを見つけることができませんでしたので、つまりはそれが0から0に出力しますREGEXP_SUBSTRあなたはすべての場合に正しい答えを得るでしょう。

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

ホスト

そして

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

ホスト



0

列内のすべての文字列にアンダースコアがない場合(...またはnull値が出力される場合)、これを覚えておいてください。

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

0

大きな文字列から部分文字列を見つけるには:

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

次に、'Ple'から文字列を見つけるには、次のようにしますString_value

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

あなたは結果を見つけるでしょう: Ple


0

文字列の位置が固定されていない場合は、以下のSelectステートメントによって期待される出力を取得できます。

テーブル構造IDVARCHAR2(100 BYTE)CLIENT VARCHAR2(4000 BYTE)

DATA- IDのCLIENT
1001 { "のclientId": "CON-BJP"、 "クライアント名": "ABC"、 "providerId": "SBS"}
1002 { "のidtype": "AccountNo"、 "ID": "XXXXXXXX3521"、 "ToPricingId": "XXXXXXXX3521"、 "clientId": "Test-Cust"、 "clientName": "MFX"}

要件-CLIENT列の「ClientId」文字列を検索し、対応する値を返します。Like From "clientId": "con-bjp"-> con-bjp(期待される出力)

CLIENT、substr(substr(CLIENT、instr(CLIENT、 '"clientId": "')+ length( '" clientId ":"'))、1、instr(substr(CLIENT、instr(CLIENT、 '"clientId" : "')+ length('" clientId ":" '))、' "'、1)-1)TEST_SCからのcut_str;

クライアントcut_str ------------------------------------------------ ----------- ---------- {"clientId": "con-bjp"、 "clientName": "ABC"、 "providerId": "SBS"} con- bjp {"IdType": "AccountNo"、 "Id": "XXXXXXXX3521"、 "ToPricingId": "XXXXXXXX3521"、 "clientId": "Test-Cust"、 "clientName": "MFX"} Test-Cust

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.