Этот тип хождения по графику - боль в SQL Сервер - у вас есть циклы. Проблема в том, чтобы избежать циклов. Поскольку SQL Сервер не имеет очень хороших типов данных, вам необходимо хранить посещенные узлы в виде строк.
Вы можете делать все это в рекурсивном CTE. Идея состоит в том, чтобы следовать всем путям от узла без повторения какого-либо узла. Держите минимум посещенных узлов. Вуаля! Это указывает путь:
with cte as (
select box, users,
convert(varchar(max), concat(',', box, ',', users, ',')) as path,
(case when box < users then box else users end) as min_node
from exchange
union all
select cte.box, e.users,
concat(cte.path, e.users, ','),
(case when min_node < e.users then min_node else e.users end)
from cte join
exchange e
on e.box = cte.users
where path not like '%,' + e.users + ',%'
)
select cte.box, min(cte.users), min(cte.path), min(cte.min_node) as grouping
from cte
group by cte.box;
Здесь - это дБ <> скрипка.
Это предполагает, что края симметричны c, поэтому если a, b), у вас также есть (b, a).
Если это не так, легко добавить CTE, который делает это так:
select box, users
from exchange
union -- on purpose to remove duplicates
select users, box
from exchange;