使用MODEL子句在有向图中查找循环

时间:2017-12-16 21:46:07

标签: sql oracle graph

我有一个包含U和V两列的表格,其中带有值的行(' a',' b')表示顶点有一条边' a& #39;到' b'。

我可以使用分层查询或递归WITH轻松找到图形中的循环,但我无法绕过MODEL子句以及查找使用它的循环。

所以,问题是:

  1. 如何使用MODEL子句在有向图中查找周期?
  2. (OR)如何使用MODEL子句实现行为,类似于分层查询或递归WITH?
  3. 表格:

    0.00 volts
    -50.00 degrees C
    -58.00 degrees F
    3.33 volts
    282.52 degrees C
    540.54 degrees F
    5.00 volts
    449.51 degrees C
    841.12 degrees F
    5.00 volts
    

    结果应如下所示:

       U   |   V      
    ----------------
       a   |   b
       b   |   c
       c   |   a
       g   |   h
       h   |   g
          ...
    

1 个答案:

答案 0 :(得分:1)

模型设计用于类似电子表格的计算,而不是用于遍历图形。

对于您的数据,您可以使用以下解决方案,它只返回正确的结果,因为存在“数据魔法” - 每个孩子都大于其父级。

column path format a15
with dag(u, v) as (
select 'a', 'b' from dual union all
select 'b', 'c' from dual union all
select 'b', 'k' from dual union all
select 'c', 'a' from dual union all
select 'g', 'h' from dual union all
select 'h', 'g' from dual)
select u, v, path || '->' || v path, instr(path, v) is_cycle
from (select t.*, case when u in ('a', 'g') then u end path from dag t)
model
dimension by (u, v)
measures (cast(path as varchar2(4000)) path, 0 cycle)
(
  path[any, any] order by u, v =
  nvl(path[cv(u), cv(v)], max(path)[any, cv(u)] || '->' || cv(u))
)
order by 1, 2;

U V PATH              IS_CYCLE
- - --------------- ----------
a b a->b                     0
b c a->b->c                  0
b k a->b->k                  0
c a a->b->c->a               1
g h g->h                     0
h g g->h->g                  1

6 rows selected.

在一般情况下,您可以使用迭代模型来模拟广度优先搜索,并在每次迭代时填充上一次迭代中标记的节点的子节点(并且尚未访问过)的路径。