Gráfico dirigido SQL

Tengo el siguiente set de datos, que representa nodos en un gráfico dirigido.

CREATE TABLE nodes (NODE_FROM VARCHAR2(10), NODE_TO VARCHAR2(10)); INSERT INTO nodes VALUES('GT','TG'); INSERT INTO nodes VALUES('GG','GC'); INSERT INTO nodes VALUES('AT','TG'); INSERT INTO nodes VALUES('TG','GC'); INSERT INTO nodes VALUES('GC','CG'); INSERT INTO nodes VALUES('TG','GG'); INSERT INTO nodes VALUES('GC','CA'); INSERT INTO nodes VALUES('CG','GT'); 

Representación visual: http://img.sesql.com/sql/image1.JPG

Usando este set de datos, quiero que un usuario ingrese un nivel (por ejemplo, 2) y esto devuelve todos los nodos 2 "saltos" lejos de un nodo específico):

 NODE_FROM NODE_TO TG GC TG GG AT TG GT TG 

http://img.sesql.com/sql/image2.JPG

Mi bash actual se ve así:

 SELECT node_from, node_to FROM nodes WHERE level <= 2 -- Display nodes two "hops" from 'AT' START WITH node_from = 'AT' CONNECT BY NOCYCLE PRIOR node_to = node_from OR node_to = PRIOR node_from GROUP BY node_from, node_to; 

http://img.sesql.com/sql/image3.JPG

Como puede ver, la relación: GT -> TG falta.

Entonces su gráfica se ve así:

texto alternativo Puede usar la function START WITH/CONNECT BY Oracle para hacer lo que quiera. Si comenzamos en el nodo GA, podemos alcanzar todos los nodos en el gráfico, como se muestra a continuación.

 CREATE TABLE edges (PARENT VARCHAR(100), CHILD VARCHAR(100)); insert into edges values ('AT', 'TG'); insert into edges values ('CG', 'GT'); insert into edges values ('GA', 'AT'); insert into edges values ('GC', 'CA'); insert into edges values ('GC', 'CG'); insert into edges values ('GG', 'GC'); insert into edges values ('GT', 'TG'); insert into edges values ('TG', 'GA'); insert into edges values ('TG', 'GC'); insert into edges values ('TG', 'GG'); COMMIT; SELECT * FROM edges START WITH CHILD = 'GA' CONNECT BY NOCYCLE PRIOR CHILD = PARENT; 

Salida:

  PARENT CHILD 1 TG GA 2 GA AT 3 AT TG 4 TG GC 5 GC CA 6 GC CG 7 CG GT 8 CG GT 9 GC CA 

NOTA Dado que su gráfico tiene ciclos, es importante utilizar la syntax NOCYCLE en CONNECT BY , de lo contrario, esto no funcionará.

RESPUESTA EDITADA EN BASE A ÚLTIMAS EDICIONES POR OP

En primer lugar, supongo que por "2 saltos" te refieres a "como máximo 2 saltos", porque tu consulta actual está utilizando el level <= 2 . Si quiere exactamente 2 saltos, debería ser level = 2 .

En su gráfico actualizado (image2.JPG), no hay una ruta de AT a GT que tome 2 saltos, por lo que la consulta devuelve lo que esperaría. Desde AT a GT, podemos ir a AT->TG->GC->CG->GT , pero eso es 4 saltos, que es mayor que 2, por eso no recuperamos ese resultado.

Si esperas poder alcanzar AT a GT en 2 saltos, entonces necesitas agregar una ventaja entre TG y GT, así:

 INSERT INTO nodes VALUES('TG','GT'); 

Ahora cuando ejecuta su consulta, obtendrá esta información de vuelta:

NODE_FROM NODE_TO EN TG TG GC TG GG TG GT

Recuerde que START WITH/CONNECT BY solo funcionará si hay una ruta entre los nodos. En su gráfico (antes de agregar el nuevo borde anterior), no hay una ruta para AT->TG->GT , por eso no obtiene el resultado.

Ahora, si agrega el borde TG->AT , entonces tendríamos la ruta GT->TG->AT . Entonces, en ese caso, AT está a 2 saltos de GT (es decir, estamos yendo en sentido inverso ahora, comenzando desde GT y terminando en AT). Pero para encontrar esos paths, necesitaría establecer START WITH node_from = 'GT'.

Si su objective es encontrar todas las routes desde un nodo de inicio a cualquier nodo objective que tenga un nivel <= 2 saltos o less, entonces lo anterior debería funcionar.

Sin embargo, si quieres encontrar todas las routes desde algún nodo objective a un nodo fuente (es decir, el ejemplo inverso que di, desde GT->TG->AT ), entonces eso no va a funcionar aquí. Tendría que ejecutar la consulta para todos los nodos en el gráfico.

Piense en START WITH/CONNECT BY haciendo una primera búsqueda en profundidad . Va a ir a todos lados desde un nodo inicial. Pero no va a hacer más que eso.

Resumen:

Creo que la consulta funciona bien, dadas las restricciones anteriores. He explicado por qué no se devuelve la ruta GT-TG , así que espero que tenga sentido.

Tenga en count, sin embargo, que si también está tratando de atravesar las routes inversas, deberá pasar por todos los nodos y ejecutar la consulta, cambiando el nodo START WITH cada vez.

Parece que necesitas get una copy de Árboles y jerarquías de Joe Celko en SQL for Smarties .