Từ nhận xét của bạn đến câu trả lời @PrzemyslawKruglej
Vấn đề chính là với truy vấn nội bộ với
connect by
, nó tạo ra số lượng hàng đáng kinh ngạc
Số lượng hàng được tạo có thể được giảm bớt bằng cách tiếp cận sau:
Bảng kiểm tra/* test table populated with sample data from your question */
SQL> create table t1(str) as(
2 select 'a;b;c' from dual union all
3 select 'b;c;d' from dual union all
4 select 'a;c;d' from dual
5 );
Table created
-- number of rows generated will solely depend on the most longest
-- string.
-- If (say) the longest string contains 3 words (wont count separator `;`)
-- and we have 100 rows in our table, then we will end up with 300 rows
-- for further processing , no more.
with occurrence(ocr) as(
select level
from ( select max(regexp_count(str, '[^;]+')) as mx_t
from t1 ) t
connect by level <= mx_t
)
select count(regexp_substr(t1.str, '[^;]+', 1, o.ocr)) as generated_for_3_rows
from t1
cross join occurrence o;
Kết quả: Đối với ba hàng trong đó hàng dài nhất được tạo thành từ ba từ, chúng tôi sẽ tạo ra 9 hàng :
GENERATED_FOR_3_ROWS
--------------------
9
Truy vấn cuối cùng:
with occurrence(ocr) as(
select level
from ( select max(regexp_count(str, '[^;]+')) as mx_t
from t1 ) t
connect by level <= mx_t
)
select res
, count(res) as cnt
from (select regexp_substr(t1.str, '[^;]+', 1, o.ocr) as res
from t1
cross join occurrence o)
where res is not null
group by res
order by res;
Kết quả:
RES CNT
----- ----------
a 2
b 2
c 3
d 2
Bản trình diễn SQLFIddle
Tìm hiểu thêm về hàm regexp_count () (11g trở lên) và regexp_substr () các hàm biểu thức chính quy.
Lưu ý: Các hàm biểu thức chính quy tương đối tốn kém để tính toán và khi cần xử lý một lượng rất lớn dữ liệu, có thể đáng xem xét chuyển sang một PL / SQL thuần túy. Đây là một ví dụ.