Oracle
 sql >> Database >  >> RDS >> Oracle

Contrassegna le persone che condividono funzionalità comuni con Oracle SQL

Ecco un modo per farlo, utilizzando una query gerarchica ("connetti per"). Il primo passo è estrarre le relazioni iniziali dai dati di base; la query gerarchica si basa sul risultato di questo primo passaggio. Ho aggiunto un'altra riga agli input per illustrare un nodo che è un componente connesso di per sé.

Hai contrassegnato i componenti collegati come A e B - ovviamente, non funzionerà se hai, ad esempio, 30.000 componenti collegati. Nella mia soluzione, utilizzo il nome minimo del nodo come indicatore per ogni componente connesso.

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
;

Uscita:

     ID   ID_GROUP
------- ----------
      1          1
      2          1
      3          3
      4          3
      5          3
      6          6

Quindi, se devi aggiungere ID_GROUP come FLAG ai dati di base, puoi farlo con un banale join.