Làm thế nào để Chọn một chuỗi con trong Oracle SQL cho đến một ký tự cụ thể?


82

Giả sử tôi có một cột trong bảng có các kết quả như:

ABC_blahblahblah
DEFGH_moreblahblahblah
IJKLMNOP_moremoremoremore

Tôi muốn có thể viết một truy vấn chọn cột này từ bảng đã nói, nhưng chỉ trả về chuỗi con tối đa là ký tự Dấu gạch dưới (_). Ví dụ:

ABC
DEFGH
IJKLMNOP

Hàm SUBSTRING dường như không phù hợp với nhiệm vụ vì nó dựa trên vị trí và vị trí của dấu gạch dưới khác nhau.

Tôi đã nghĩ về hàm TRIM (cụ thể là hàm RTRIM):

SELECT RTRIM('listofchars' FROM somecolumn) 
FROM sometable

Nhưng tôi không chắc mình sẽ làm việc này như thế nào vì nó dường như chỉ xóa một danh sách / bộ ký tự nhất định và tôi thực sự chỉ theo dõi các ký tự dẫn đến ký tự Dấu gạch dưới.

Câu trả lời:


141

Sử dụng kết hợp SUBSTR, INSTR và NVL (đối với các chuỗi không có dấu gạch dưới) sẽ trả về những gì bạn muốn:

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

Kết quả:

output
------
ABC

Sử dụng:

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

Tài liệu tham khảo:

Phụ lục

Nếu sử dụng Oracle10g +, bạn có thể sử dụng regex qua REGEXP_SUBSTR .


Cảm ơn. Rất thanh lịch! (Thật tốt khi biết về REGEXP_SUBSTR.) Tôi thậm chí còn không nghĩ đến việc tìm kiếm hỗ trợ Regex trong Oracle.
Pretzel

Trong Oracle, bạn có thể tạo các hàm (độc lập hoặc trong một gói) và sử dụng chúng trong một câu lệnh chọn.
bart

9
Không thành công nếu chạy với các giá trị KHÔNG chứa chuỗi con bạn đang tìm kiếm. instrtrả về 0 nếu bạn có INSTR('ABC/D', '_'). Cuối cùng, bạn có một chuỗi con từ 0 đến (0-1) là null. Không tốt.
Marcel Stör

39

Điều này có thể được thực hiện dễ dàng bằng REGEXP_SUBSTR .

Hãy sử dụng

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

trong đó STRING_EXAMPLE là chuỗi của bạn.

Thử:

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

Nó sẽ giải quyết vấn đề của bạn.


1
Tôi ủng hộ điều này cùng với giải pháp được chọn bởi OP vì nó thực hiện một thủ thuật. Tuy nhiên, điều đáng chú ý là giải pháp này chậm hơn nhiều so với giải pháp của @OMG Ponies, đặc biệt nếu được sử dụng ở những nơi có điều kiện. Các thử nghiệm của tôi đã cho thấy hiệu suất của truy vấn giống hệt nhau chậm hơn khoảng 6 lần. Câu hỏi này đi xa hơn nữa về chủ đề stackoverflow.com/questions/41156391/...
Ister

Trong thử nghiệm của tôi, INSTRgiải pháp hoạt động khá nhanh ngang với REGEXPgiải pháp.
alexherm

7

Bạn cần lấy vị trí của dấu gạch dưới đầu tiên (sử dụng INSTR) và sau đó lấy một phần của chuỗi từ trình sửa lỗi thứ nhất đến (pos-1) bằng cách sử dụng substr.

  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

Tài liệu hướng dẫn

Tài liệu Susbtr


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

là câu trả lời đúng, như được đăng bởi user1717270

Nếu bạn sử dụng INSTR, nó sẽ cung cấp cho bạn vị trí cho một chuỗi giả sử nó có chứa "_" trong đó. Nếu không thì sao? Vâng, câu trả lời sẽ là 0. Do đó, khi bạn muốn in chuỗi, nó sẽ in ra a NULL. Ví dụ: Nếu bạn muốn xóa miền khỏi "host.domain". Trong một số trường hợp, bạn sẽ chỉ có tên ngắn gọn, tức là "máy chủ". Nhiều khả năng bạn muốn in "host". Vâng, với INSTRnó sẽ cho bạn một NULLvì nó không tìm thấy bất kỳ "." Nào, tức là nó sẽ in từ 0 đến 0. Với nó, REGEXP_SUBSTRbạn sẽ nhận được câu trả lời đúng trong mọi trường hợp:

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

TỔ CHỨC

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

TỔ CHỨC



0

Hãy nhớ điều này nếu tất cả các Chuỗi của bạn trong cột không có dấu gạch dưới (... hoặc nếu không giá trị null sẽ là đầu ra):

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

0

Để tìm bất kỳ chuỗi con nào từ chuỗi lớn:

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

Sau đó, để tìm chuỗi 'Ple'từ String_valuechúng ta có thể làm như sau:

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

Bạn sẽ tìm thấy kết quả: Ple


0

Trong trường hợp nếu vị trí chuỗi không cố định thì bằng câu lệnh Select bên dưới chúng ta có thể nhận được kết quả mong đợi.

Cấu trúc bảng ID VARCHAR2 (100 BYTE) CLIENT VARCHAR2 (4000 BYTE)

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

Yêu cầu - Tìm kiếm chuỗi "ClientId" trong cột CLIENT và trả về giá trị tương ứng. Giống như Từ "clientId": "con-bjp" -> con-bjp (Đầu ra mong đợi)

chọn CLIENT, substr (substr (CLIENT, Guid (CLIENT, '"clientId": "') + length ('" clientId ":"')), 1, hướng dẫn (substr (CLIENT, Guid (CLIENT, '"clientId") : "') + length ('" clientId ":" ')),' "', 1) -1) cut_str từ 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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.