Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

Tìm tất cả các kết quả phù hợp trong varchar2 ()

Câu hỏi tuyệt vời! Đây là một Fiddle hiển thị cách truy vấn các kết quả phù hợp thành một tập kết quả.

Và đây là lời giải thích dài trong trường hợp truy vấn trong Fiddle không có ý nghĩa :)

Tôi đang sử dụng một bảng có tên RegEx_Test với một cột MyVal . Đây là nội dung của bảng:

MyVal
------------------------------
[A1][abc][B23][D123]a33[bx5]
[Z15][ax0][B0][F13]R3
[X215][A3A][J99]F33F33G24[43][R3]
[Z99][c1][F3][d33]3x24[Y3][f13]
[9a][D41][Q39][XX12]B27[T03][J12]

Regexp của bạn trong suốt là thế này:\[[[:alpha:]][[:digit:]]{1,2}\] . Nó giống như trong câu trả lời khác ngoại trừ với POSIX :alpha::digit: các chỉ báo, an toàn hơn trong trường hợp các bộ ký tự quốc tế.

Đầu tiên, bạn cần biết số lượng trận đấu tối đa trên bất kỳ dòng nào. Sử dụng REGEXP_COUNT cho điều này:

SELECT MAX(REGEXP_COUNT(MyVal, '\[[[:alpha:]][[:digit:]]{1,2}\]'))
  FROM Regex_Test

MAX(REGEXP_COUNT(My...
----------------------
                     6

Sử dụng số lượng tối đa đó để nhận bảng "bộ đếm" (đó là SELECT ... FROM DUAL bên dưới) và kết hợp chéo bảng bộ đếm với một truy vấn sẽ kéo các giá trị của bạn bằng cách sử dụng REGEXP_SUBSTR . REGEXP_SUBSTR có tham số "lần xuất hiện" và tham số đó sẽ sử dụng Counter :

SELECT
  MyVal,
  Counter,
  REGEXP_SUBSTR(MyVal, '\[[[:alpha:]][[:digit:]]{1,2}\]', 1, Counter) Matched
FROM Regex_Test
CROSS JOIN (
   SELECT LEVEL Counter
   FROM DUAL
   CONNECT BY LEVEL <= (
     SELECT MAX(REGEXP_COUNT(MyVal, '\[[[:alpha:]][[:digit:]]{1,2}\]'))
     FROM Regex_Test)) Counters

Đây là một mẫu chạy với bảng của tôi (kết quả một phần):

MyVal                              Counter Matched
---------------------------------- ------- -------
[9a][D41][Q39][XX12]B27[T03][J12]        1 [D41]
[9a][D41][Q39][XX12]B27[T03][J12]        2 [Q39]
[9a][D41][Q39][XX12]B27[T03][J12]        3 [T03]
[9a][D41][Q39][XX12]B27[T03][J12]        4 [J12]
[9a][D41][Q39][XX12]B27[T03][J12]        5
[9a][D41][Q39][XX12]B27[T03][J12]        6
[A1][abc][B23][D123]a33[bx5]             1 [A1]
[A1][abc][B23][D123]a33[bx5]             2 [B23]
[A1][abc][B23][D123]a33[bx5]             3
... and so on - total is 30 rows

Tại thời điểm này, bạn có một tập hợp kết quả của các kết quả phù hợp riêng lẻ, cộng với các giá trị rỗng trong đó một hàng có ít hơn các kết quả phù hợp tối đa. Các trận đấu vẫn có dấu ngoặc kép xung quanh của họ. Bao quanh toàn bộ vấn đề bằng một truy vấn bên ngoài sẽ lọc ra các giá trị rỗng và loại bỏ các dấu ngoặc và bạn có danh sách cuối cùng của mình:

SELECT SUBSTR(Matched, 2, LENGTH(Matched)-2) FROM (
  SELECT
    MyVal,
    Counter,
    REGEXP_SUBSTR(MyVal, '\[[[:alpha:]][[:digit:]]{1,2}\]', 1, Counter) Matched
  FROM Regex_Test
  CROSS JOIN (
     SELECT LEVEL Counter
     FROM DUAL
     CONNECT BY LEVEL <= (
       SELECT MAX(REGEXP_COUNT(MyVal, '\[[[:alpha:]][[:digit:]]{1,2}\]'))
       FROM Regex_Test)) Counters
) WHERE Matched IS NOT NULL

Đây là truy vấn trên Fiddle và nó có thể được sử dụng trong một truy vấn khác.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Làm cách nào để so sánh các giá trị cho mục nhập cuối cùng và mục nhập cuối cùng thứ hai trong bảng?

  2. OCIError về vấn đề quyền 'yêu cầu'?

  3. Thay đổi mật khẩu người dùng qua jdbc. Sự cố với đường chuyền có chứa dấu chấm hỏi

  4. tải dữ liệu XLS khổng lồ vào Oracle bằng python

  5. Làm cách nào để tìm kiếm một trường khi bạn gặp lỗi ORA-19011?