Tengo una tabla de SQL Server en la que cada fila representa una ventaja en una red de gráficos. El FromNodeID y ToNodeID son claves externas a una tabla de nodos, y el esquema es algo como esto:Consulta eficiente de una tabla dirigida/no dirigida de bordes de gráficos en SQL Server
CREATE TABLE #Edges (
EdgeID int identity (1,1),
FromNodeID int,
ToNodeID int
);
INSERT INTO #Edges (FromNodeID, ToNodeID) VALUES
(1,2),
(1,3),
(1,4),
(2,3),
(3,5),
(4,5),
(5,6);
Ahora, si considero cada borde que será dirigida (es decir, de una forma), entonces es fácil de resolver todos esos nodos a los que puedo acceder directamente desde cualquier nodo. Yo añadiría un índice para la columna de la FromNodeID, a continuación, ejecutar una consulta como esta:
SELECT ToNodeID FROM #Edges WHERE FromNodeID = 3
Resultado: 5
Pero ¿cuál sería la mejor manera de estructurar mi mesa/consulta si quiero tratar cada borde como unidireccional. es decir, a partir del nodo 3, me gustaría obtener los resultados:
Resultado: 1, 2, 5
La forma más simple que puedo pensar sería la de añadir un índice adicional a la columna y luego ToNodeID ejecutar una consulta como esta:
SELECT ToNodeID FROM #Edges WHERE FromNodeID = 3
UNION SELECT FromNodeID FROM #Edges WHERE ToNodeID = 3;
Pero esto obviamente implica la combinación de conjuntos de resultados a partir de dos preguntas y no parece muy eficiente - ¿existe una mejor manera de escribir esto en una sola consulta? (Tenga en cuenta que no quiero volver a insertar los bordes invertidos en la tabla; necesito poder tratar los bordes como dirigidos o no dirigidos en el tiempo de ejecución).
¡Gracias por cualquier consejo!
Si '# Edges' está asegurado desde casos con FromNodeID = ToNodeID, su versión de UNION ganaría usando' UNION ALL' en lugar de 'UNION'. E incluso si se permiten los nodos autorreferenciales, sería mejor utilizar 'SELECT ... WHERE FromNodeID = 3 AND ToNodeID <> 3 UNION ALL SELECT ... WHERE FromNodeID <> 3 AND ToNodeID = 3 UNION ALL SELECT 3 FROM #Edges WHERE FromNodeID = 3 AND ToNodeID = 3', pero solo si no necesita clasificar los nodos (de lo contrario, parece tener un peor rendimiento que su versión). –