Tengo un árbol con una estructura como esta:Cómo etiquetar adecuadamente las ramas de un árbol en una primera búsqueda en profundidad
__2__3__4
/ \__5__6
0__1___7/__8__9
\\
\\__10__11__12
\__ __ __
13 14 15
nodo 1 tiene cuatro hijos (2,7,10,13), los nodos 2 y 7 tienen dos hijos cada uno (ambos comparten el nodo 5 como un niño). Lo que estoy tratando de hacer es crear un CET que proporcionan los registros que contienen el nodo padre, el nodo, la distancia de la raíz y la rama (o tenedor) su contenido en.
IF (OBJECT_ID('tempdb..#Discovered') IS NOT NULL)
BEGIN
DROP TABLE #Discovered
END
CREATE TABLE #Discovered
(
ID int PRIMARY KEY NOT NULL,
Predecessor int NULL,
OrderDiscovered int
);
INSERT INTO #Discovered (ID, Predecessor, OrderDiscovered)
VALUES (@nodeId, NULL, 0);
--loop through node connections table in a breadth first manner
WHILE @@ROWCOUNT > 0
BEGIN
INSERT INTO #Discovered (ID, Predecessor, OrderDiscovered)
SELECT c.node2_id
,MIN(c.node1_id)
,MIN(d.OrderDiscovered) + 1
FROM #Discovered d JOIN node_connections c ON d.ID = c.node1_id
WHERE c.node2_id NOT IN (SELECT ID FROM #Discovered)
GROUP BY c.node2_id
END;
SELECT * FROM #Discovered;
WITH BacktraceCTE(Id, Predecessor, OrderDiscovered, Path, fork)
AS
(
SELECT d.ID, d.Predecessor, d.OrderDiscovered, CAST(d.ID AS varchar(MAX)), 0
FROM #Discovered d
WHERE d.Id = @itemId
UNION ALL
-- Recursive member, select all the nodes which have the previous
SELECT d.ID, d.Predecessor, d.OrderDiscovered,
CAST(cte.Path + '->' + CAST(d.ID as varchar(10)) as varchar(MAX)),
fork + CONVERT (Integer, ROW_NUMBER() OVER (ORDER BY d.ID)) - 1
FROM #Discovered d JOIN BacktraceCTE cte ON d.Predecessor = cte.ID
)
SELECT Predecessor as node1_id, OrderDiscovered as hop, fork, ID as node2_id, Path FROM BacktraceCTE
ORDER BY fork, OrderDiscovered;
El problema es con cómo se calcula el tenedor Cada vez que el CTE vuelve a un nivel anterior, solo tiene disponibles los números de fila y cuál era el número de horquilla en ese nivel. Lo que me gustaría lograr es registros en los que cada combinación de salto y tenedor sea única.
Sin embargo, con el código anterior voy a conseguir los resultados que dicen nodo 2 a 5 terminan siendo hop 3 tenedor 1 y el nodo 7 a 5 también terminar siendo hop 3 tenedor 1.
Aquí está el árbol de nuevo con el etiquetado de las ramas con la forma en que deben aparecer:
__2__3__4 :0
/ \__5__6 :1,2
0__1___7/__8__9 :3
\\
\\__10__11__12 :4
\__ __ __
13 14 15 :5
Como se puede ver por las horquillas 1 y 2, creo que el mejor método sería contar la rama dos veces dándole su propio identificador de este modo preservar la unicidad de la combinación de hop y tenedor.
Por favor, ayúdame a averiguar qué debo hacer para lograr esto. Siento que esto debería ser posible con un CTE, pero quizás estoy equivocado y, si lo fuera, me encantaría saber cuál sería el mejor método para abordarlo.
EDITAR El conjunto de resultados se vería así:
predecesor, ID, Orden Descubierto, Camino, Tenedor
nula, 0, 0, 0, 0
0, 1, 1, 0-> 1, 0
1, 2, 2, 0-> 1-> 2, 0
2, 3, 3, 0-> 1-> 2-> 3, 0
3, 4, 4, 0-> 1-> 2-> 3-> 4, 0
2, 5, 3, 0-> 1-> 2-> 5, 1
5, 6, 4, 0-> 1-> 2-> 5-> 6, 1
1, 7, 2, 0-> 1-> 7, 2
7, 5, 3, 0-> 1-> 7-> 5, 2
5, 6, 4, 0-> 1-> 7-> 5-> 6, 2
7, 8, 3, 0-> 1-> 7-> 8, 3
8, 9, 4, 0-> 1-> 7-> 8-> 9, 3
1, 10, 2, 0-> 1-> 10, 4
10 , 11, 3, 0-> 1-> 10-> 11, 4
11, 12, 4, 0-> 1-> 10-> 11-> 12, 4
1, 13, 2, 0-> 1-> 13, 5
13, 14, 3, 0-> 1-> 13-> 14, 5
14, 15, 4, 0-> 1-> 13-> 14-> 15, 5
Desde el nodo '5' tiene dos padres, esto es ** ** No es un árbol, sino simplemente un gráfico ** ** – AakashM
¿Puede dar un script con la estructura de la tabla y los datos de ejemplo, y ¿cuál es el conjunto de resultados deseado para esa información? –
@AakashM - No es simplemente un gráfico, sino un gráfico dirigido (también conocido como digraph). – HABO