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을 통해 regex를 사용할 수 있습니다 .


감사. 매우 우아합니다! (REGEXP_SUBSTR에 대해서도 알아두면 좋습니다.) Oracle에서 Regex 지원을 찾을 생각조차하지 않았습니다.
Pretzel

Oracle에서는 함수 (독립 실행 형 또는 패키지)를 만들고 select 문에서 사용할 수 있습니다.
bart

9
찾고있는 부분 문자열을 포함하지 않는 값에 대해 실행하면 실패합니다. instr있는 경우 0을 반환합니다 INSTR('ABC/D', '_'). 결국 0에서 (0-1)까지의 하위 문자열이 있으며 이는 null입니다. 안좋다.
Marcel Stör 2011

39

REGEXP_SUBSTR을 사용하면 쉽게 할 수 있습니다.

사용하시기 바랍니다

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

여기서 STRING_EXAMPLE 은 문자열입니다.

시험:

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

그것은 당신의 문제를 해결할 것입니다.


1
나는 트릭을 수행하기 때문에 OP가 선택한 솔루션을 따라 이것을 upvoting하고 있습니다. 그러나이 솔루션이 @OMG Ponies의 솔루션보다 훨씬 느리다는 점은 주목할 가치가 있습니다. 특히 where 조건에서 사용하는 경우 더욱 그렇습니다. 내 테스트는 동일한 쿼리의 수행 속도가 약 6 배 더 느린 것으로 나타났습니다. 이 질문은 주제 stackoverflow.com/questions/41156391/
Ister

내 테스트에서 INSTR솔루션은 솔루션만큼 빠르게 수행 REGEXP됩니다.
alexherm

7

INSTR을 사용하여 첫 번째 밑줄의 위치를 ​​얻은 다음 substr을 사용하여 첫 번째 문자에서 (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"에서 도메인을 제거하려는 경우. 어떤 경우에는 "호스트"와 같은 짧은 이름 만 가질 수 있습니다. 대부분 "호스트"를 인쇄하고 싶을 것입니다. 음, "."를 찾지 못했기 때문에 INSTRa를 제공합니다 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 문으로 예상 출력을 얻을 수 있습니다.

테이블 구조 ID VARCHAR2 (100 BYTE) CLIENT VARCHAR2 (4000 BYTE)

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

요구 사항-CLIENT 열에서 "ClientId"문자열을 검색하고 해당 값을 반환합니다. 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;

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.