поиск двунаправленных соединений в таблице - PullRequest
1 голос
/ 17 февраля 2009

У меня есть следующий набор результатов SQL (в результате объединения FWIW):

A,C
B,E
C,A
D,A

Каждое значение представляет узел. Таким образом, общий набор задействованных узлов - это A, B, C, D, E. Каждый ряд описывает направленное ребро.

A -> C
B -> E
C -> A
D -> A

Конечно, это можно упростить до

A <-> C
B -> E
D -> A

Теперь я хотел бы отфильтровать строки, которые не имеют двунаправленного аналога. Таким образом, окончательный набор результатов должен быть

A,C
C,A

или

A,C

в этом случае.

Я ищу лучший способ выразить это в SQL.

Ответы [ 3 ]

1 голос
/ 17 февраля 2009

Представьте таблицу узлов с колонками Node1 и Node2.

SELECT node1, node2
FROM nodes n
WHERE EXISTS (SELECT 1 FROM nodes WHERE node1 = n.node2 AND node2 = n.node1)

Конечно, вы захотите убедиться, что он проиндексирован, а именно:

(node1, node2)

и

(node2, node1)

Это все равно даст вам A, C и C, A. Чтобы отфильтровать их, измените запрос на:

SELECT node1, node2
FROM nodes n
WHERE EXISTS (SELECT 1 FROM nodes WHERE node1 = n.node2 AND node2 = n.node1)
AND node1 < node2

при условии, что есть естественный порядок, которым вы можете воспользоваться.

0 голосов
/ 17 февраля 2009

Внутреннее присоединение пар узлов к себе?

select node1, node2
from nodes n
inner join nodes n2
on n.node1 = n2.node2 and n.node2 = n2.node1

(замените узлы вашим подзапросом)

0 голосов
/ 17 февраля 2009

-- Temp table creating to insert example rows
SELECT 
'A' AS Col1, 'C' AS Col2
INTO #TEMP
UNION
SELECT 'B', 'E'
UNION
SELECT 'C', 'A'
UNION
SELECT 'D', 'A'


SELECT A.* FROM #TEMP A, #TEMP B
WHERE (A.COL1 = B.COL2 AND A.COL2 = B.COL1)


Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...