Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Sinalize indivíduos que compartilham recursos comuns com o Oracle SQL


Aqui está uma maneira de fazer isso, usando uma consulta hierárquica ("conectar por"). O primeiro passo é extrair os relacionamentos iniciais dos dados de base; a consulta hierárquica é construída no resultado desta primeira etapa. Adicionei mais uma linha às entradas para ilustrar um nó que é um componente conectado por si só.

Você marcou os componentes conectados como A e B - claro, isso não funcionará se você tiver, digamos, 30.000 componentes conectados. Na minha solução, uso o nome do nó mínimo como marcador para cada componente conectado.
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
;

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

Então, se você precisar adicionar o ID_GROUP como um FLAG aos dados base, poderá fazê-lo com uma junção trivial.