Ho una tabella server SQL in cui ogni riga rappresenta un bordo in una rete di grafici. Il FromNodeID e ToNodeID sono chiavi esterne a una tabella di nodo, e lo schema è qualcosa di simile:Interrogazione efficiente di una tabella diretta/non indirizzata di spigoli del grafico in 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);
Ora, se considero ogni bordo che sarà diretto (cioè, solo andata), quindi è facile da lavorare fuori tutti quei nodi che posso ottenere direttamente da qualsiasi nodo. Mi piacerebbe aggiungere un indice alla colonna FromNodeID, e quindi eseguire una query come questa:
SELECT ToNodeID FROM #Edges WHERE FromNodeID = 3
Risultato: 5
Ma quale sarebbe il modo migliore per strutturare la mia tabella/query se voglio tratta ogni spigolo come unidirezionale. cioè a partire dal nodo 3, mi piacerebbe ottenere i risultati:
Risultato: 1, 2, 5
Il modo più semplice che posso pensare sarebbe quello di aggiungere un indice aggiuntivo alla colonna ToNodeID e poi eseguire una query come questa:
SELECT ToNodeID FROM #Edges WHERE FromNodeID = 3
UNION SELECT FromNodeID FROM #Edges WHERE ToNodeID = 3;
Ma questo ovviamente comporta set combinando risultato da due query e non sembra molto efficiente - c'è un modo migliore per scrivere questo in una singola query? (Si noti che non voglio inserire nuovamente i bordi invertiti nella tabella - Devo essere in grado di trattare i bordi come diretti o non diretti in fase di esecuzione).
Grazie per qualsiasi consiglio!
Se '# bordi 'è protetto dai casi con FromNodeID = ToNodeID, la versione UNION vincerebbe dall'uso di' UNION ALL' invece di 'UNION'. E anche se i nodi autoreferenziali sono consentiti, sarebbe meglio usare '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', ma solo se non hai bisogno di ordinare i nodi (altrimenti sembra che abbia prestazioni peggiori rispetto alla tua versione). –