假设我有一个图,其顶点已编号。在表中,我存储图的边,即 边的起点和终点的顶点编号。如何递归提取与给定顶点相关的所有顶点?
我如何尝试做到这一点:
WITH vals AS (
SELECT 1 A, 2 B FROM DUAL UNION ALL
SELECT 1 A, 5 B FROM DUAL UNION ALL
SELECT 1 A, 6 B FROM DUAL UNION ALL
SELECT 2 A, 3 B FROM DUAL UNION ALL
SELECT 2 A, 6 B FROM DUAL UNION ALL
SELECT 3 A, 4 B FROM DUAL UNION ALL
SELECT 4 A, 1 B FROM DUAL UNION ALL
SELECT 6 A, 7 B FROM DUAL UNION ALL
SELECT 2 A, 7 B FROM DUAL UNION ALL
SELECT 8 A, 9 B FROM DUAL )
SELECT LEVEL, A, B FROM VALS
START WITH A = 1 -- предположим, ищем связанные с этой вершиной рёбра
CONNECT BY NOCYCLE PRIOR B = A
ORDER BY LEVEL, A;
我能得到什么:
LEVEL, A, B
1,1,5
1,1,2
1,1,6 -- Первый вход вершины 6
2,2,7
2,2,6 -- Второй вход вошедшей вершины 6
2,2,3
2,6,7 -- Первое упоминание ребра
3,3,4
3,6,7 -- Второе упоминание ребра
4,4,1
5,1,5
5,1,6
6,6,7 -- Третье упоминание ребра
但由于某种原因,5、1、2 没有重复。
我想得到什么:
和/或相关顶点的列表
VERTEX_NAME
1
2
3
4
5
6
7
和/或不重复提及已包含的顶点的边列表
LEVEL, A, B
1,1,5
1,1,2
1,1,6
2,2,7
2,2,3
3,3,4

如果你制作边链,那么当边重复时,预言机就会停止,但它可以多次经过同一个顶点。
为了降低复杂性,您需要在重复顶点时切断链,而不是边。
为此,您可以将顶点添加到边列表中并收集链,交替顶点和边。
上面的答案通常是有效的,但它的复杂性增加得很快。如果您采用 11 个顶点并将每个顶点连接起来,那么在某个时刻,RAM 中将有数千万行。这是我的要求。它在大约1.5秒内“吞掉”了所描述的图(对于这样的图,我什至10分钟都没有等待上面算法的实现)。
当然,您可以尝试使用更复杂的图,以确保算法不仅仅拉出所有顶点:
这就是它的样子(上次我从顶点 2 开始,所以它是有色的):