Пытаясь не выбирать одно и то же соединение несколько раз, я пытался использовать условие charindex () = 0 следующим образом:
WITH Cluster(calling_party, called_party, link_strength, Path)
AS
(SELECT
calling_party,
called_party,
link_strength,
CONVERT(varchar(max), calling_party + '.' + called_party) AS Path
FROM
monthly_connections_test
WHERE
link_strength > 0.1 AND
calling_party = 'b'
UNION ALL
SELECT
mc.calling_party,
mc.called_party,
mc.link_strength,
CONVERT(varchar(max), cl.Path + '.' + mc.calling_party + '.' + mc.called_party) AS Path
FROM
monthly_connections_test mc
INNER JOIN Cluster cl ON
(
mc.called_party = cl.called_party OR
mc.called_party = cl.calling_party
) AND
(
CHARINDEX(cl.called_party + '.' + mc.calling_party, Path) = 0 AND
CHARINDEX(cl.called_party + '.' + mc.called_party, Path) = 0
)
WHERE
mc.link_strength > 0.1
)
SELECT
calling_party,
called_party,
link_strength,
Path
FROM
Cluster OPTION (maxrecursion 30000)
Условие, однако, не выполняет свое назначение, поскольку несколько строк выбираются несколькораз.
Фактическая цель здесь - получить весь кластер соединений, к которому принадлежит выбранный пользователь (в примере пользователя b).
Edit1:
Я попытался изменить запрос следующим образом:
With combined_users AS
(SELECT calling_party CALLING, called_party CALLED, link_strength FROM dbo.monthly_connections_test WHERE link_strength > 0.1),
related_users1 AS
(
SELECT c.CALLING, c.CALLED, c.link_strength, CONVERT(varchar(max), '.' + c.CALLING + '.' + c.CALLED + '.') path from combined_users c where CALLING = 'a1'
UNION ALL
SELECT c.CALLING, c.CALLED, c.link_strength,
convert(varchar(max),r.path + c.CALLED + '.') path
from combined_users c
join related_users1 r
ON (c.CALLING = r.CALLED) and CHARINDEX(c.CALLING + '.' + c.CALLED + '.', r.path)= 0
),
related_users2 AS
(
SELECT c.CALLING, c.CALLED, c.link_strength, CONVERT(varchar(max), '.' + c.CALLING + '.' + c.CALLED + '.') path from combined_users c where CALLED = 'a1'
UNION ALL
SELECT c.CALLING, c.CALLED, c.link_strength,
convert(varchar(max),r.path + c.CALLING + '.') path
from combined_users c
join related_users2 r
ON c.CALLED = r.CALLING and CHARINDEX('.' + c.CALLING + '.' + c.CALLED, r.path)= 0
)
SELECT CALLING, CALLED, link_strength, path FROM
(SELECT CALLING, CALLED, link_strength, path FROM related_users1 UNION SELECT CALLING, CALLED, link_strength, path FROM related_users2) r OPTION (MAXRECURSION 30000)
Чтобы проверить запрос, я создал кластер ниже:
Запросвыше вернулась следующая таблица:
a1 a2 1.0000000 .a1.a2.
a11 a13 1.0000000 .a12.a1.a13.a11.
a12 a1 1.0000000 .a12.a1.
a13 a12 1.0000000 .a12.a1.a13.
a14 a13 1.0000000 .a12.a1.a13.a14.
a15 a14 1.0000000 .a12.a1.a13.a14.a15.
a2 a10 1.0000000 .a1.a2.a10.
a2 a3 1.0000000 .a1.a2.a3.
a3 a4 1.0000000 .a1.a2.a3.a4.
a3 a6 1.0000000 .a1.a2.a3.a6.
a4 a8 1.0000000 .a1.a2.a3.a4.a8.
a4 a9 1.0000000 .a1.a2.a3.a4.a9.
Запрос явно возвращает соединения с выбранным узлом и соединения в противоположном направлении.Проблема заключается в смене направления: например, соединения a7, a4 и a11, a10 не выбраны, поскольку направление изменяется (относительно начального узла).
Кто-нибудь знает, как изменить запрос в порядкевключить все соединения?
Спасибо