Đây là một cách để thực hiện việc này, sử dụng truy vấn phân cấp ("kết nối bằng"). Bước đầu tiên là trích xuất các mối quan hệ ban đầu từ dữ liệu cơ sở; truy vấn phân cấp được xây dựng dựa trên kết quả từ bước đầu tiên này. Tôi đã thêm một hàng nữa vào các đầu vào để minh họa một nút tự nó là một thành phần được kết nối.
Bạn đã đánh dấu các thành phần được kết nối là A và B - tất nhiên, điều đó sẽ không hoạt động nếu bạn có, chẳng hạn như 30.000 thành phần được kết nối. Trong giải pháp của mình, tôi sử dụng tên nút tối thiểu làm điểm đánh dấu cho mỗi thành phần được kết nối.
with
sample_data (id, feature) as (
select 1, 1 from dual union all
select 1, 2 from dual union all
select 1, 3 from dual union all
select 2, 3 from dual union all
select 2, 4 from dual union all
select 2, 6 from dual union all
select 3, 5 from dual union all
select 3, 10 from dual union all
select 3, 12 from dual union all
select 4, 12 from dual union all
select 4, 18 from dual union all
select 5, 10 from dual union all
select 5, 30 from dual union all
select 6, 40 from dual
)
-- select * from sample_data; /*
, initial_rel(id_base, id_linked) as (
select distinct s1.id, s2.id
from sample_data s1 join sample_data s2
on s1.feature = s2.feature and s1.id <= s2.id
)
-- select * from initial_rel; /*
select id_linked as id, min(connect_by_root(id_base)) as id_group
from initial_rel
start with id_base <= id_linked
connect by nocycle prior id_linked = id_base and id_base < id_linked
group by id_linked
order by id_group, id
;
Đầu ra:
ID ID_GROUP
------- ----------
1 1
2 1
3 3
4 3
5 3
6 6
Sau đó, nếu bạn cần thêm ID_GROUP dưới dạng CỜ vào dữ liệu cơ sở, bạn có thể làm như vậy với một phép nối nhỏ.