标记与 Oracle SQL 具有共同特征的个人

Posted

技术标签:

【中文标题】标记与 Oracle SQL 具有共同特征的个人【英文标题】:Flag individuals that share common features with Oracle SQL 【发布时间】:2018-10-03 14:14:36 【问题描述】:

考虑下表:

ID  Feature
1   1
1   2
1   3
2   3
2   4
2   6
3   5
3   10
3   12
4   12
4   18
5   10
5   30

我想根据重叠的特征对个人进行分组。如果其中两个组再次具有重叠的特征,我会将两者视为一组。应重复此过程,直到组之间没有重叠的特征。上表中此过程的结果将是:

ID  Feature Flag
1   1       A
1   2       A
1   3       A
2   3       A
2   4       A
2   6       A
3   5       B
3   10      B
3   12      B
4   12      B
4   18      B
5   10      B
5   30      B

所以实际上我要解决的问题是在图中找到连接的组件。这里 [1,2,3] 是 ID 为 1 的图(参见 https://en.wikipedia.org/wiki/Connectivity_(graph_theory))。这个问题相当于this problem,不过我想用Oracle SQL来解决。

【问题讨论】:

您使用的是什么版本的 Oracle? 我使用的是 12c 版本 如果这是连接 1:1,1:2,2:3,3:5 等,我不明白为什么 3:5 应该在 B 组中,而另一个在 A 组中?跨度> ID 3 和 4 有共同的特征 12,让我们调用 ID 3 和 4 组 x。 ID 3 和 5 具有共同特征 10,让我们将 ID 3 和 5 称为组 y。现在组 x 和 y 有共同的特征 12。因此 3,4 和 5 属于一个组。 @K.Roelofs 。 . .然后就有希望使用递归 CTE 解决问题。 【参考方案1】:

这是执行此操作的一种方法,使用分层(“连接方式”)查询。第一步是从基础数据中提取初始关系;分层查询建立在第一步的结果之上。我在输入中再添加一行来说明一个节点本身就是一个连接的组件。

您将连接的组件标记为 A 和 B - 当然,如果您有 30,000 个连接的组件,这将不起作用。在我的解决方案中,我使用最小节点名称作为每个连接组件的标记。

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
;

输出:

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

然后,如果您需要将 ID_GROUP 作为 FLAG 添加到基础数据中,您可以使用普通连接来完成。

【讨论】:

以上是关于标记与 Oracle SQL 具有共同特征的个人的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Oracle SQL 中的 XML 标记中进行搜索?

面向对象的三大特征

计算两个配置文件之间的相似性以获得共同特征的数量

ios中具有共同特征的自定义单元格

集合的表示方法之描述法中啥是取值范围和共同特征

类与对象